mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-20 11:36:25 +08:00
feat(server): support refresh token (#15218)
This commit is contained in:
@@ -18,14 +18,10 @@ import {
|
||||
URLHelper,
|
||||
UseNamedGuard,
|
||||
} from '../../base';
|
||||
import {
|
||||
OAuthCallbackBodySchema,
|
||||
OAuthPreflightBodySchema,
|
||||
Public,
|
||||
SessionIssuer,
|
||||
} from '../../core/auth';
|
||||
import { Public, SessionIssuer } from '../../core/auth';
|
||||
import { OAuthProviderName } from './config';
|
||||
import { OAuthProviderFactory } from './factory';
|
||||
import { OAuthCallbackBodySchema, OAuthPreflightBodySchema } from './input';
|
||||
import { OAuthService } from './service';
|
||||
|
||||
@Controller('/api/oauth')
|
||||
@@ -48,6 +44,16 @@ export class OAuthController {
|
||||
if (fields.has('client_nonce')) {
|
||||
throw new MissingOauthQueryParameter({ name: 'client_nonce' });
|
||||
}
|
||||
if (fields.has('client')) {
|
||||
throw new ActionForbidden();
|
||||
}
|
||||
if (fields.has('provider')) {
|
||||
const provider =
|
||||
body && typeof body === 'object' && 'provider' in body
|
||||
? String(body.provider)
|
||||
: '';
|
||||
throw new UnknownOauthProvider({ name: provider });
|
||||
}
|
||||
throw new MissingOauthQueryParameter({ name: 'provider' });
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const OAuthProviderSchema = z.enum([
|
||||
'Google',
|
||||
'GitHub',
|
||||
'Apple',
|
||||
'OIDC',
|
||||
]);
|
||||
|
||||
export const OAuthClientSchema = z.enum([
|
||||
'web',
|
||||
'affine',
|
||||
'affine-canary',
|
||||
'affine-beta',
|
||||
'affine-dev',
|
||||
]);
|
||||
|
||||
export const OAuthPreflightBodySchema = z
|
||||
.object({
|
||||
provider: OAuthProviderSchema,
|
||||
redirect_uri: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(2048)
|
||||
.nullish()
|
||||
.transform(value => value ?? undefined),
|
||||
client: OAuthClientSchema,
|
||||
client_nonce: z.string().min(1).max(512),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const OAuthCallbackBodySchema = z
|
||||
.object({
|
||||
code: z.string().min(1).max(4096),
|
||||
state: z.string().min(1).max(16_384),
|
||||
client_nonce: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(512)
|
||||
.nullish()
|
||||
.transform(value => value ?? undefined),
|
||||
// Apple includes this JSON field on the first form_post callback.
|
||||
user: z.string().max(16_384).optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const OAuthStateEnvelopeSchema = z
|
||||
.object({
|
||||
state: z.string().uuid(),
|
||||
provider: OAuthProviderSchema,
|
||||
client: OAuthClientSchema,
|
||||
flow: z.enum(['popup', 'redirect']).optional(),
|
||||
pkce: z
|
||||
.object({
|
||||
codeChallenge: z.string().min(1).max(512),
|
||||
codeChallengeMethod: z.literal('S256'),
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
})
|
||||
.strict();
|
||||
@@ -15,12 +15,12 @@ import {
|
||||
import {
|
||||
AuthChallengeStore,
|
||||
AuthService,
|
||||
OAuthStateEnvelopeSchema,
|
||||
type VerifiedIdentity,
|
||||
} from '../../core/auth';
|
||||
import { Models } from '../../models';
|
||||
import { OAuthProviderName } from './config';
|
||||
import { OAuthProviderFactory } from './factory';
|
||||
import { OAuthStateEnvelopeSchema } from './input';
|
||||
import { OAuthAccount, Tokens } from './providers/def';
|
||||
import { OAuthPkceChallenge, OAuthState } from './types';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user