chore: drop old client support (#14369)

This commit is contained in:
DarkSky
2026-02-05 02:49:33 +08:00
committed by GitHub
parent de29e8300a
commit 403f16b404
103 changed files with 3293 additions and 997 deletions
@@ -13,6 +13,7 @@ import { ConnectedAccount } from '@prisma/client';
import type { Request, Response } from 'express';
import {
ActionForbidden,
Config,
InvalidAuthState,
InvalidOauthCallbackState,
@@ -57,6 +58,9 @@ export class OAuthController {
if (!unknownProviderName) {
throw new MissingOauthQueryParameter({ name: 'provider' });
}
if (!clientNonce) {
throw new MissingOauthQueryParameter({ name: 'client_nonce' });
}
const providerName = OAuthProviderName[unknownProviderName];
const provider = this.providerFactory.get(providerName);
@@ -67,6 +71,10 @@ export class OAuthController {
const pkce = provider.requiresPkce ? this.oauth.createPkcePair() : null;
if (redirectUri && !this.url.isAllowedRedirectUri(redirectUri)) {
throw new ActionForbidden();
}
const state = await this.oauth.saveOAuthState({
provider: providerName,
redirectUri,
@@ -173,16 +181,6 @@ export class OAuthController {
);
}
// TODO(@fengmk2): clientNonce should be required after the client version >= 0.21.0
if (
state.clientNonce &&
state.clientNonce !== clientNonce &&
// apple sign in with nonce stored in id token
state.provider !== OAuthProviderName.Apple
) {
throw new InvalidAuthState();
}
if (!state.provider) {
throw new MissingOauthQueryParameter({ name: 'provider' });
}
@@ -193,6 +191,13 @@ export class OAuthController {
throw new UnknownOauthProvider({ name: state.provider ?? 'unknown' });
}
if (
state.provider !== OAuthProviderName.Apple &&
(!clientNonce || !state.clientNonce || state.clientNonce !== clientNonce)
) {
throw new InvalidAuthState();
}
let tokens: Tokens;
try {
tokens = await provider.getToken(code, state);
@@ -221,7 +226,7 @@ export class OAuthController {
state.provider === OAuthProviderName.Apple &&
(!state.client || state.client === 'web')
) {
return res.redirect(this.url.link(state.redirectUri ?? '/'));
return this.url.safeRedirect(res, state.redirectUri ?? '/');
}
res.send({
@@ -1,38 +1,17 @@
import {
Context,
registerEnumType,
ResolveField,
Resolver,
} from '@nestjs/graphql';
import type { Request } from 'express';
import semver from 'semver';
import { registerEnumType, ResolveField, Resolver } from '@nestjs/graphql';
import { getClientVersionFromRequest } from '../../base';
import { ServerConfigType } from '../../core/config/types';
import { OAuthProviderName } from './config';
import { OAuthProviderFactory } from './factory';
registerEnumType(OAuthProviderName, { name: 'OAuthProviderType' });
const APPLE_OAUTH_PROVIDER_MIN_VERSION = new semver.Range('>=0.22.0', {
includePrerelease: true,
});
@Resolver(() => ServerConfigType)
export class OAuthResolver {
constructor(private readonly factory: OAuthProviderFactory) {}
@ResolveField(() => [OAuthProviderName])
oauthProviders(@Context() ctx: { req: Request }) {
// Apple oauth provider is not supported in client version < 0.22.0
const providers = this.factory.providers;
if (providers.includes(OAuthProviderName.Apple)) {
const version = getClientVersionFromRequest(ctx.req);
if (!version || !APPLE_OAUTH_PROVIDER_MIN_VERSION.test(version)) {
return providers.filter(p => p !== OAuthProviderName.Apple);
}
}
return providers;
oauthProviders() {
return this.factory.providers;
}
}