mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 05:37:32 +00:00
feat(server): support access token (#13372)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Introduced user access tokens, enabling users to generate, list, and revoke personal access tokens via the GraphQL API. * Added GraphQL mutations and queries for managing access tokens, including token creation (with optional expiration), listing, and revocation. * Implemented authentication support for private API endpoints using access tokens in addition to session cookies. * **Bug Fixes** * None. * **Tests** * Added comprehensive tests for access token creation, listing, revocation, expiration handling, and authentication using tokens. * **Chores** * Updated backend models, schema, and database migrations to support access token functionality. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
mutation generateUserAccessToken($input: GenerateAccessTokenInput!) {
|
||||
generateUserAccessToken(input: $input) {
|
||||
id
|
||||
name
|
||||
token
|
||||
createdAt
|
||||
expiresAt
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
query listUserAccessTokens {
|
||||
accessTokens {
|
||||
id
|
||||
name
|
||||
createdAt
|
||||
expiresAt
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation revokeUserAccessToken($id: String!) {
|
||||
revokeUserAccessToken(id: $id)
|
||||
}
|
||||
@@ -70,6 +70,41 @@ export const licenseBodyFragment = `fragment licenseBody on License {
|
||||
validatedAt
|
||||
variant
|
||||
}`;
|
||||
export const generateUserAccessTokenMutation = {
|
||||
id: 'generateUserAccessTokenMutation' as const,
|
||||
op: 'generateUserAccessToken',
|
||||
query: `mutation generateUserAccessToken($input: GenerateAccessTokenInput!) {
|
||||
generateUserAccessToken(input: $input) {
|
||||
id
|
||||
name
|
||||
token
|
||||
createdAt
|
||||
expiresAt
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const listUserAccessTokensQuery = {
|
||||
id: 'listUserAccessTokensQuery' as const,
|
||||
op: 'listUserAccessTokens',
|
||||
query: `query listUserAccessTokens {
|
||||
accessTokens {
|
||||
id
|
||||
name
|
||||
createdAt
|
||||
expiresAt
|
||||
}
|
||||
}`,
|
||||
};
|
||||
|
||||
export const revokeUserAccessTokenMutation = {
|
||||
id: 'revokeUserAccessTokenMutation' as const,
|
||||
op: 'revokeUserAccessToken',
|
||||
query: `mutation revokeUserAccessToken($id: String!) {
|
||||
revokeUserAccessToken(id: $id)
|
||||
}`,
|
||||
};
|
||||
|
||||
export const adminServerConfigQuery = {
|
||||
id: 'adminServerConfigQuery' as const,
|
||||
op: 'adminServerConfig',
|
||||
|
||||
@@ -37,6 +37,14 @@ export interface Scalars {
|
||||
Upload: { input: File; output: File };
|
||||
}
|
||||
|
||||
export interface AccessToken {
|
||||
__typename?: 'AccessToken';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
expiresAt: Maybe<Scalars['DateTime']['output']>;
|
||||
id: Scalars['String']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
export interface AddContextBlobInput {
|
||||
blobId: Scalars['String']['input'];
|
||||
contextId: Scalars['String']['input'];
|
||||
@@ -985,6 +993,11 @@ export interface ForkChatSessionInput {
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface GenerateAccessTokenInput {
|
||||
expiresAt?: InputMaybe<Scalars['DateTime']['input']>;
|
||||
name: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface GrantDocUserRolesInput {
|
||||
docId: Scalars['String']['input'];
|
||||
role: DocRole;
|
||||
@@ -1396,6 +1409,7 @@ export interface Mutation {
|
||||
/** Create a chat session */
|
||||
forkCopilotSession: Scalars['String']['output'];
|
||||
generateLicenseKey: Scalars['String']['output'];
|
||||
generateUserAccessToken: RevealedAccessToken;
|
||||
grantDocUserRoles: Scalars['Boolean']['output'];
|
||||
grantMember: Scalars['Boolean']['output'];
|
||||
/** import users */
|
||||
@@ -1443,6 +1457,7 @@ export interface Mutation {
|
||||
revokePublicDoc: DocType;
|
||||
/** @deprecated use revokePublicDoc instead */
|
||||
revokePublicPage: DocType;
|
||||
revokeUserAccessToken: Scalars['Boolean']['output'];
|
||||
sendChangeEmail: Scalars['Boolean']['output'];
|
||||
sendChangePasswordEmail: Scalars['Boolean']['output'];
|
||||
sendSetPasswordEmail: Scalars['Boolean']['output'];
|
||||
@@ -1650,6 +1665,10 @@ export interface MutationGenerateLicenseKeyArgs {
|
||||
sessionId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationGenerateUserAccessTokenArgs {
|
||||
input: GenerateAccessTokenInput;
|
||||
}
|
||||
|
||||
export interface MutationGrantDocUserRolesArgs {
|
||||
input: GrantDocUserRolesInput;
|
||||
}
|
||||
@@ -1790,6 +1809,10 @@ export interface MutationRevokePublicPageArgs {
|
||||
workspaceId: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationRevokeUserAccessTokenArgs {
|
||||
id: Scalars['String']['input'];
|
||||
}
|
||||
|
||||
export interface MutationSendChangeEmailArgs {
|
||||
callbackUrl: Scalars['String']['input'];
|
||||
email?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -2094,6 +2117,7 @@ export interface PublicUserType {
|
||||
|
||||
export interface Query {
|
||||
__typename?: 'Query';
|
||||
accessTokens: Array<AccessToken>;
|
||||
/** get the whole app configuration */
|
||||
appConfig: Scalars['JSONObject']['output'];
|
||||
/** Apply updates to a doc using LLM and return the merged markdown. */
|
||||
@@ -2288,6 +2312,15 @@ export interface ReplyUpdateInput {
|
||||
id: Scalars['ID']['input'];
|
||||
}
|
||||
|
||||
export interface RevealedAccessToken {
|
||||
__typename?: 'RevealedAccessToken';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
expiresAt: Maybe<Scalars['DateTime']['output']>;
|
||||
id: Scalars['String']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
token: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
export interface RevokeDocUserRoleInput {
|
||||
docId: Scalars['String']['input'];
|
||||
userId: Scalars['String']['input'];
|
||||
@@ -3010,6 +3043,46 @@ export interface TokenType {
|
||||
token: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
export type GenerateUserAccessTokenMutationVariables = Exact<{
|
||||
input: GenerateAccessTokenInput;
|
||||
}>;
|
||||
|
||||
export type GenerateUserAccessTokenMutation = {
|
||||
__typename?: 'Mutation';
|
||||
generateUserAccessToken: {
|
||||
__typename?: 'RevealedAccessToken';
|
||||
id: string;
|
||||
name: string;
|
||||
token: string;
|
||||
createdAt: string;
|
||||
expiresAt: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
export type ListUserAccessTokensQueryVariables = Exact<{
|
||||
[key: string]: never;
|
||||
}>;
|
||||
|
||||
export type ListUserAccessTokensQuery = {
|
||||
__typename?: 'Query';
|
||||
accessTokens: Array<{
|
||||
__typename?: 'AccessToken';
|
||||
id: string;
|
||||
name: string;
|
||||
createdAt: string;
|
||||
expiresAt: string | null;
|
||||
}>;
|
||||
};
|
||||
|
||||
export type RevokeUserAccessTokenMutationVariables = Exact<{
|
||||
id: Scalars['String']['input'];
|
||||
}>;
|
||||
|
||||
export type RevokeUserAccessTokenMutation = {
|
||||
__typename?: 'Mutation';
|
||||
revokeUserAccessToken: boolean;
|
||||
};
|
||||
|
||||
export type AdminServerConfigQueryVariables = Exact<{ [key: string]: never }>;
|
||||
|
||||
export type AdminServerConfigQuery = {
|
||||
@@ -6184,6 +6257,11 @@ export type GrantWorkspaceTeamMemberMutation = {
|
||||
};
|
||||
|
||||
export type Queries =
|
||||
| {
|
||||
name: 'listUserAccessTokensQuery';
|
||||
variables: ListUserAccessTokensQueryVariables;
|
||||
response: ListUserAccessTokensQuery;
|
||||
}
|
||||
| {
|
||||
name: 'adminServerConfigQuery';
|
||||
variables: AdminServerConfigQueryVariables;
|
||||
@@ -6536,6 +6614,16 @@ export type Queries =
|
||||
};
|
||||
|
||||
export type Mutations =
|
||||
| {
|
||||
name: 'generateUserAccessTokenMutation';
|
||||
variables: GenerateUserAccessTokenMutationVariables;
|
||||
response: GenerateUserAccessTokenMutation;
|
||||
}
|
||||
| {
|
||||
name: 'revokeUserAccessTokenMutation';
|
||||
variables: RevokeUserAccessTokenMutationVariables;
|
||||
response: RevokeUserAccessTokenMutation;
|
||||
}
|
||||
| {
|
||||
name: 'createChangePasswordUrlMutation';
|
||||
variables: CreateChangePasswordUrlMutationVariables;
|
||||
|
||||
Reference in New Issue
Block a user