mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-19 11:06:25 +08:00
feat: improve selfhosted login (#14502)
fix #13397 fix #14011 #### PR Dependency Tree * **PR #14502** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Centralized CORS policy with dynamic origin validation applied to server and realtime connections * Improved sign-in flows with contextual, localized error hints and toast notifications * Centralized network-error normalization and conditional OAuth provider fetching * **Bug Fixes** * Better feedback for self-hosted connection failures and clearer authentication error handling * More robust handling of network-related failures with user-friendly messages <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { UserFriendlyError } from '@affine/error';
|
||||
import {
|
||||
gqlFetcherFactory,
|
||||
type OauthProvidersQuery,
|
||||
@@ -11,6 +12,45 @@ import { Store } from '@toeverything/infra';
|
||||
export type ServerConfigType = ServerConfigQuery['serverConfig'] &
|
||||
OauthProvidersQuery['serverConfig'];
|
||||
|
||||
const NETWORK_ERROR_PATTERNS = [
|
||||
/failed to fetch/i,
|
||||
/network request failed/i,
|
||||
/fetch failed/i,
|
||||
/load failed/i,
|
||||
/networkerror/i,
|
||||
/cors/i,
|
||||
/certificate/i,
|
||||
/ssl/i,
|
||||
/err_[a-z_]+/i,
|
||||
];
|
||||
|
||||
function mapServerConfigError(error: unknown) {
|
||||
const userFriendlyError = UserFriendlyError.fromAny(error);
|
||||
if (
|
||||
userFriendlyError.is('NETWORK_ERROR') ||
|
||||
userFriendlyError.is('REQUEST_ABORTED') ||
|
||||
userFriendlyError.is('TOO_MANY_REQUEST')
|
||||
) {
|
||||
return userFriendlyError;
|
||||
}
|
||||
|
||||
if (error instanceof Error) {
|
||||
const detail = `${error.name}: ${error.message}`;
|
||||
if (NETWORK_ERROR_PATTERNS.some(pattern => pattern.test(detail))) {
|
||||
return new UserFriendlyError({
|
||||
status: 504,
|
||||
code: 'NETWORK_ERROR',
|
||||
type: 'NETWORK_ERROR',
|
||||
name: 'NETWORK_ERROR',
|
||||
message: detail,
|
||||
stacktrace: error.stack,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return userFriendlyError;
|
||||
}
|
||||
|
||||
export class ServerConfigStore extends Store {
|
||||
constructor() {
|
||||
super();
|
||||
@@ -20,19 +60,13 @@ export class ServerConfigStore extends Store {
|
||||
serverBaseUrl: string,
|
||||
abortSignal?: AbortSignal
|
||||
): Promise<ServerConfigType> {
|
||||
const gql = gqlFetcherFactory(`${serverBaseUrl}/graphql`, globalThis.fetch);
|
||||
const serverConfigData = await gql({
|
||||
query: serverConfigQuery,
|
||||
context: {
|
||||
signal: abortSignal,
|
||||
headers: {
|
||||
'x-affine-version': BUILD_CONFIG.appVersion,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (serverConfigData.serverConfig.features.includes(ServerFeature.OAuth)) {
|
||||
const oauthProvidersData = await gql({
|
||||
query: oauthProvidersQuery,
|
||||
try {
|
||||
const gql = gqlFetcherFactory(
|
||||
`${serverBaseUrl}/graphql`,
|
||||
globalThis.fetch
|
||||
);
|
||||
const serverConfigData = await gql({
|
||||
query: serverConfigQuery,
|
||||
context: {
|
||||
signal: abortSignal,
|
||||
headers: {
|
||||
@@ -40,11 +74,26 @@ export class ServerConfigStore extends Store {
|
||||
},
|
||||
},
|
||||
});
|
||||
return {
|
||||
...serverConfigData.serverConfig,
|
||||
...oauthProvidersData.serverConfig,
|
||||
};
|
||||
if (
|
||||
serverConfigData.serverConfig.features.includes(ServerFeature.OAuth)
|
||||
) {
|
||||
const oauthProvidersData = await gql({
|
||||
query: oauthProvidersQuery,
|
||||
context: {
|
||||
signal: abortSignal,
|
||||
headers: {
|
||||
'x-affine-version': BUILD_CONFIG.appVersion,
|
||||
},
|
||||
},
|
||||
});
|
||||
return {
|
||||
...serverConfigData.serverConfig,
|
||||
...oauthProvidersData.serverConfig,
|
||||
};
|
||||
}
|
||||
return { ...serverConfigData.serverConfig, oauthProviders: [] };
|
||||
} catch (error) {
|
||||
throw mapServerConfigError(error);
|
||||
}
|
||||
return { ...serverConfigData.serverConfig, oauthProviders: [] };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user