0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-20 21:32:31 -05:00

feat(github): getUserInfo (#188)

* feat(github): getUserInfo

* fix: pr
This commit is contained in:
Wang Sijie 2022-01-21 20:47:14 +08:00 committed by GitHub
parent 872b1d6450
commit d78aa07f7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 8 deletions

View file

@ -1,3 +1,4 @@
export const authorizationEndpoint = 'https://github.com/login/oauth/authorize';
export const scope = 'read:user';
export const accessTokenEndpoint = 'https://github.com/login/oauth/access_token';
export const userInfoEndpoint = 'https://api.github.com/user';

View file

@ -1,8 +1,8 @@
import nock from 'nock';
import { getAccessToken, getAuthorizationUri, validateConfig } from '.';
import { getAccessToken, getAuthorizationUri, validateConfig, getUserInfo } from '.';
import { getConnectorConfig } from '../utilities';
import { accessTokenEndpoint, authorizationEndpoint } from './constant';
import { accessTokenEndpoint, authorizationEndpoint, userInfoEndpoint } from './constant';
jest.mock('../utilities');
@ -51,3 +51,21 @@ describe('validateConfig', () => {
await expect(validateConfig({ clientId: 'clientId' })).rejects.toThrowError();
});
});
describe('getUserInfo', () => {
it('shoud get valid SocialUserInfo', async () => {
nock(userInfoEndpoint).get('').reply(200, {
id: 1,
avatar_url: 'https://github.com/images/error/octocat_happy.gif',
name: 'monalisa octocat',
email: 'octocat@github.com',
});
const socialUserInfo = await getUserInfo('code');
expect(socialUserInfo).toMatchObject({
id: '1',
avatar: 'https://github.com/images/error/octocat_happy.gif',
name: 'monalisa octocat',
email: 'octocat@github.com',
});
});
});

View file

@ -9,9 +9,10 @@ import {
GetAccessToken,
GetAuthorizationUri,
ValidateConfig,
GetUserInfo,
} from '../types';
import { getConnectorConfig } from '../utilities';
import { authorizationEndpoint, accessTokenEndpoint, scope } from './constant';
import { authorizationEndpoint, accessTokenEndpoint, scope, userInfoEndpoint } from './constant';
export const metadata: ConnectorMetadata = {
id: 'github',
@ -56,6 +57,12 @@ export const getAuthorizationUri: GetAuthorizationUri = async (redirectUri, stat
};
export const getAccessToken: GetAccessToken = async (code) => {
type AccessTokenResponse = {
access_token: string;
scope: string;
token_type: string;
};
const { clientId: client_id, clientSecret: client_secret } =
await getConnectorConfig<GithubConfig>(metadata.id, metadata.type);
const { access_token: accessToken } = await got
@ -67,10 +74,34 @@ export const getAccessToken: GetAccessToken = async (code) => {
code,
},
})
.json<{
access_token: string;
scope: string;
token_type: string;
}>();
.json<AccessTokenResponse>();
return accessToken;
};
export const getUserInfo: GetUserInfo = async (accessToken: string) => {
type UserInfoResponse = {
id: number;
avatar_url: string;
email: string;
name: string;
};
const {
id,
avatar_url: avatar,
email,
name,
} = await got
.get(userInfoEndpoint, {
headers: {
authorization: `token ${accessToken}`,
},
})
.json<UserInfoResponse>();
return {
id: String(id),
avatar,
email,
name,
};
};

View file

@ -24,6 +24,7 @@ export interface EmailConector extends BaseConnector {
export interface SocialConector extends BaseConnector {
getAuthorizationUri: GetAuthorizationUri;
getAccessToken: GetAccessToken;
getUserInfo: GetUserInfo;
}
export interface EmailMessageTypes {
@ -56,3 +57,13 @@ export type ValidateConfig<T extends ConnectorConfig = ConnectorConfig> = (
export type GetAuthorizationUri = (redirectUri: string, state: string) => Promise<string>;
export type GetAccessToken = (code: string) => Promise<string>;
export type GetUserInfo = (accessToken: string) => Promise<SocialUserInfo>;
export interface SocialUserInfo {
id: string;
email?: string;
phone?: string;
name?: string;
avatar?: string;
}