mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
102 lines
2.5 KiB
TypeScript
102 lines
2.5 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
|
|
import { Config, InvalidOauthCallbackCode, URLHelper } from '../../../base';
|
|
import { OAuthProviderName } from '../config';
|
|
import { AutoRegisteredOAuthProvider } from '../register';
|
|
|
|
interface AuthTokenResponse {
|
|
access_token: string;
|
|
scope: string;
|
|
token_type: string;
|
|
}
|
|
|
|
export interface UserInfo {
|
|
login: string;
|
|
email: string;
|
|
avatar_url: string;
|
|
name: string;
|
|
}
|
|
|
|
@Injectable()
|
|
export class GithubOAuthProvider extends AutoRegisteredOAuthProvider {
|
|
provider = OAuthProviderName.GitHub;
|
|
|
|
constructor(
|
|
protected readonly AFFiNEConfig: Config,
|
|
private readonly url: URLHelper
|
|
) {
|
|
super();
|
|
}
|
|
|
|
getAuthUrl(state: string) {
|
|
return `https://github.com/login/oauth/authorize?${this.url.stringify({
|
|
client_id: this.config.clientId,
|
|
redirect_uri: this.url.link('/oauth/callback'),
|
|
scope: 'user',
|
|
...this.config.args,
|
|
state,
|
|
})}`;
|
|
}
|
|
|
|
async getToken(code: string) {
|
|
const response = await fetch(
|
|
'https://github.com/login/oauth/access_token',
|
|
{
|
|
method: 'POST',
|
|
body: this.url.stringify({
|
|
code,
|
|
client_id: this.config.clientId,
|
|
client_secret: this.config.clientSecret,
|
|
redirect_uri: this.url.link('/oauth/callback'),
|
|
}),
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
}
|
|
);
|
|
|
|
if (response.ok) {
|
|
const ghToken = (await response.json()) as AuthTokenResponse;
|
|
|
|
return {
|
|
accessToken: ghToken.access_token,
|
|
scope: ghToken.scope,
|
|
};
|
|
} else {
|
|
const body = await response.text();
|
|
if (response.status < 500) {
|
|
throw new InvalidOauthCallbackCode({ status: response.status, body });
|
|
}
|
|
throw new Error(
|
|
`Server responded with non-success status ${response.status}, body: ${body}`
|
|
);
|
|
}
|
|
}
|
|
|
|
async getUser(token: string) {
|
|
const response = await fetch('https://api.github.com/user', {
|
|
method: 'GET',
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
});
|
|
|
|
if (response.ok) {
|
|
const user = (await response.json()) as UserInfo;
|
|
|
|
return {
|
|
id: user.login,
|
|
avatarUrl: user.avatar_url,
|
|
email: user.email,
|
|
};
|
|
} else {
|
|
throw new Error(
|
|
`Server responded with non-success code ${
|
|
response.status
|
|
} ${await response.text()}`
|
|
);
|
|
}
|
|
}
|
|
}
|