mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat(github): getAuthorizeUri (#185)
* feat(github): getAuthorizeUri * fix: authorizationEndpoint
This commit is contained in:
parent
81aaa4a083
commit
ea756752e8
4 changed files with 69 additions and 1 deletions
2
packages/core/src/connectors/github/constant.ts
Normal file
2
packages/core/src/connectors/github/constant.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const authorizationEndpoint = 'https://github.com/login/oauth/authorize';
|
||||
export const scope = 'read:user';
|
17
packages/core/src/connectors/github/index.test.ts
Normal file
17
packages/core/src/connectors/github/index.test.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { getAuthorizeUri } from '.';
|
||||
import { getConnectorConfig } from '../utilities';
|
||||
import { authorizationEndpoint } from './constant';
|
||||
|
||||
jest.mock('../utilities');
|
||||
|
||||
describe('getAuthorizeUri', () => {
|
||||
it('should get a valid uri by redirectUri and state', async () => {
|
||||
(getConnectorConfig as jest.MockedFunction<typeof getConnectorConfig>).mockResolvedValue({
|
||||
clientId: 'log_xx',
|
||||
});
|
||||
const authorizeUri = await getAuthorizeUri('http://localhost:3000/callback', 'some_state');
|
||||
expect(authorizeUri).toEqual(
|
||||
`${authorizationEndpoint}?client_id=log_xx&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&scope=read%3Auser&state=some_state`
|
||||
);
|
||||
});
|
||||
});
|
38
packages/core/src/connectors/github/index.ts
Normal file
38
packages/core/src/connectors/github/index.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { ConnectorType } from '@logto/schemas';
|
||||
import { stringify } from 'query-string';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ConnectorMetadata, GetAuthorizeUri } from '../types';
|
||||
import { getConnectorConfig } from '../utilities';
|
||||
import { authorizationEndpoint, scope } from './constant';
|
||||
|
||||
export const metadata: ConnectorMetadata = {
|
||||
id: 'github',
|
||||
type: ConnectorType.Social,
|
||||
name: {
|
||||
en: 'Sign In with GitHub',
|
||||
zh_CN: 'GitHub登录',
|
||||
},
|
||||
logo: './logo.png',
|
||||
description: {
|
||||
en: 'Sign In with GitHub',
|
||||
zh_CN: 'GitHub登录',
|
||||
},
|
||||
};
|
||||
|
||||
const githubConfigGuard = z.object({
|
||||
clientId: z.string(),
|
||||
clientSecret: z.string(),
|
||||
});
|
||||
|
||||
type GithubConfig = z.infer<typeof githubConfigGuard>;
|
||||
|
||||
export const getAuthorizeUri: GetAuthorizeUri = async (redirectUri, state) => {
|
||||
const config = await getConnectorConfig<GithubConfig>(metadata.id, metadata.type);
|
||||
return `${authorizationEndpoint}?${stringify({
|
||||
client_id: config.clientId,
|
||||
redirect_uri: redirectUri,
|
||||
state,
|
||||
scope, // Only support fixed scope for v1.
|
||||
})}`;
|
||||
};
|
|
@ -10,11 +10,20 @@ export interface ConnectorMetadata {
|
|||
}
|
||||
|
||||
// The name `Connector` is used for database, use `ConnectorInstance` to avoid confusing.
|
||||
export interface ConnectorInstance {
|
||||
export type ConnectorInstance = EmailConector | SocialConector;
|
||||
|
||||
export interface BaseConnector {
|
||||
metadata: ConnectorMetadata;
|
||||
}
|
||||
|
||||
export interface EmailConector extends BaseConnector {
|
||||
sendMessage: EmailSendMessageFunction;
|
||||
}
|
||||
|
||||
export interface SocialConector extends BaseConnector {
|
||||
getAuthorizeUri: GetAuthorizeUri;
|
||||
}
|
||||
|
||||
export interface EmailMessageTypes {
|
||||
SignIn: {
|
||||
code: string;
|
||||
|
@ -41,3 +50,5 @@ export class ConnectorConfigError extends ConnectorError {}
|
|||
export type ValidateConfig<T extends ConnectorConfig = ConnectorConfig> = (
|
||||
config: T
|
||||
) => Promise<void>;
|
||||
|
||||
export type GetAuthorizeUri = (redirectUri: string, state: string) => Promise<string>;
|
||||
|
|
Loading…
Reference in a new issue