From 35b1f73b514a8b9118068ff9fa379f5ddd78a469 Mon Sep 17 00:00:00 2001 From: tamaina Date: Sun, 4 Jun 2023 16:41:45 +0000 Subject: [PATCH] wip --- .../core/entities/AuthSessionEntityService.ts | 3 +- .../api/endpoints/auth/session/generate.ts | 45 +------- .../server/api/endpoints/auth/session/show.ts | 50 +------- .../api/endpoints/auth/session/userkey.ts | 63 +--------- packages/misskey-js/src/endpoints.ts | 108 +++++++++++++++++- packages/misskey-js/src/entities.ts | 6 +- packages/misskey-js/src/schemas.ts | 2 + .../misskey-js/src/schemas/auth-session.ts | 19 +++ packages/misskey-js/test-d/schemas.ts | 4 + 9 files changed, 149 insertions(+), 151 deletions(-) create mode 100644 packages/misskey-js/src/schemas/auth-session.ts diff --git a/packages/backend/src/core/entities/AuthSessionEntityService.ts b/packages/backend/src/core/entities/AuthSessionEntityService.ts index b7edc8494..60e22ba0e 100644 --- a/packages/backend/src/core/entities/AuthSessionEntityService.ts +++ b/packages/backend/src/core/entities/AuthSessionEntityService.ts @@ -6,6 +6,7 @@ import type { AuthSession } from '@/models/entities/AuthSession.js'; import type { User } from '@/models/entities/User.js'; import { AppEntityService } from './AppEntityService.js'; import { bindThis } from '@/decorators.js'; +import { Packed } from 'misskey-js'; @Injectable() export class AuthSessionEntityService { @@ -21,7 +22,7 @@ export class AuthSessionEntityService { public async pack( src: AuthSession['id'] | AuthSession, me?: { id: User['id'] } | null | undefined, - ) { + ): Promise> { const session = typeof src === 'object' ? src : await this.authSessionsRepository.findOneByOrFail({ id: src }); return await awaitAll({ diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts index 6108d8202..5e25b002f 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/generate.ts @@ -7,47 +7,10 @@ import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['auth'], - - requireCredential: false, - - res: { - type: 'object', - optional: false, nullable: false, - properties: { - token: { - type: 'string', - optional: false, nullable: false, - }, - url: { - type: 'string', - optional: false, nullable: false, - format: 'url', - }, - }, - }, - - errors: { - noSuchApp: { - message: 'No such app.', - code: 'NO_SUCH_APP', - id: '92f93e63-428e-4f2f-a5a4-39e1407fe998', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - appSecret: { type: 'string' }, - }, - required: ['appSecret'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'auth/session/genrate'> { + name = 'auth/session/genrate' as const; constructor( @Inject(DI.config) private config: Config, @@ -60,14 +23,14 @@ export default class extends Endpoint { private idService: IdService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { // Lookup app const app = await this.appsRepository.findOneBy({ secret: ps.appSecret, }); if (app == null) { - throw new ApiError(meta.errors.noSuchApp); + throw new ApiError(this.meta.errors.noSuchApp); } // Generate token diff --git a/packages/backend/src/server/api/endpoints/auth/session/show.ts b/packages/backend/src/server/api/endpoints/auth/session/show.ts index db3bf7aa6..ddfaade15 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/show.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/show.ts @@ -5,66 +5,24 @@ import { AuthSessionEntityService } from '@/core/entities/AuthSessionEntityServi import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['auth'], - - requireCredential: false, - - errors: { - noSuchSession: { - message: 'No such session.', - code: 'NO_SUCH_SESSION', - id: 'bd72c97d-eba7-4adb-a467-f171b8847250', - }, - }, - - res: { - type: 'object', - optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', - }, - app: { - type: 'object', - optional: false, nullable: false, - ref: 'App', - }, - token: { - type: 'string', - optional: false, nullable: false, - }, - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - token: { type: 'string' }, - }, - required: ['token'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'auth/session/show'> { + name = 'auth/session/show' as const; constructor( @Inject(DI.authSessionsRepository) private authSessionsRepository: AuthSessionsRepository, private authSessionEntityService: AuthSessionEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { // Lookup session const session = await this.authSessionsRepository.findOneBy({ token: ps.token, }); if (session == null) { - throw new ApiError(meta.errors.noSuchSession); + throw new ApiError(this.meta.errors.noSuchSession); } return await this.authSessionEntityService.pack(session, me); diff --git a/packages/backend/src/server/api/endpoints/auth/session/userkey.ts b/packages/backend/src/server/api/endpoints/auth/session/userkey.ts index b1e7bbfde..e71296d60 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/userkey.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/userkey.ts @@ -5,61 +5,10 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { DI } from '@/di-symbols.js'; import { ApiError } from '../../../error.js'; -export const meta = { - tags: ['auth'], - - requireCredential: false, - - res: { - type: 'object', - optional: false, nullable: false, - properties: { - accessToken: { - type: 'string', - optional: false, nullable: false, - }, - - user: { - type: 'object', - optional: false, nullable: false, - ref: 'UserDetailedNotMe', - }, - }, - }, - - errors: { - noSuchApp: { - message: 'No such app.', - code: 'NO_SUCH_APP', - id: 'fcab192a-2c5a-43b7-8ad8-9b7054d8d40d', - }, - - noSuchSession: { - message: 'No such session.', - code: 'NO_SUCH_SESSION', - id: '5b5a1503-8bc8-4bd0-8054-dc189e8cdcb3', - }, - - pendingSession: { - message: 'This session is not completed yet.', - code: 'PENDING_SESSION', - id: '8c8a4145-02cc-4cca-8e66-29ba60445a8e', - }, - }, -} as const; - -export const paramDef = { - type: 'object', - properties: { - appSecret: { type: 'string' }, - token: { type: 'string' }, - }, - required: ['appSecret', 'token'], -} as const; - // eslint-disable-next-line import/no-default-export @Injectable() -export default class extends Endpoint { +export default class extends Endpoint<'auth/session/userkey'> { + name = 'auth/session/userkey' as const; constructor( @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -75,14 +24,14 @@ export default class extends Endpoint { private userEntityService: UserEntityService, ) { - super(meta, paramDef, async (ps, me) => { + super(async (ps, me) => { // Lookup app const app = await this.appsRepository.findOneBy({ secret: ps.appSecret, }); if (app == null) { - throw new ApiError(meta.errors.noSuchApp); + throw new ApiError(this.meta.errors.noSuchApp); } // Fetch token @@ -92,11 +41,11 @@ export default class extends Endpoint { }); if (session == null) { - throw new ApiError(meta.errors.noSuchSession); + throw new ApiError(this.meta.errors.noSuchSession); } if (session.userId == null) { - throw new ApiError(meta.errors.pendingSession); + throw new ApiError(this.meta.errors.pendingSession); } // Lookup access token diff --git a/packages/misskey-js/src/endpoints.ts b/packages/misskey-js/src/endpoints.ts index 6476841d6..7c6de1fd3 100644 --- a/packages/misskey-js/src/endpoints.ts +++ b/packages/misskey-js/src/endpoints.ts @@ -2341,7 +2341,113 @@ export const endpoints = { $ref: 'https://misskey-hub.net/api/schemas/App', }, }], - } + }, + //#endregion + + //#region auth + 'auth/session/genrate': { + tags: ['auth'], + + requireCredential: false, + + errors: { + noSuchApp: { + message: 'No such app.', + code: 'NO_SUCH_APP', + id: '92f93e63-428e-4f2f-a5a4-39e1407fe998', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + appSecret: { type: 'string' }, + }, + required: ['appSecret'], + }, + res: { + type: 'object', + properties: { + token: { type: 'string' }, + url: { type: 'string', format: 'url' }, + }, + required: ['token', 'url'], + }, + }], + }, + 'auth/session/show': { + tags: ['auth'], + + requireCredential: false, + + errors: { + noSuchSession: { + message: 'No such session.', + code: 'NO_SUCH_SESSION', + id: 'bd72c97d-eba7-4adb-a467-f171b8847250', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + token: { type: 'string' }, + }, + required: ['token'], + }, + res: { + $ref: 'https://misskey-hub.net/api/schemas/AuthSession', + }, + }], + }, + 'auth/session/userkey': { + tags: ['auth'], + + requireCredential: false, + + errors: { + noSuchApp: { + message: 'No such app.', + code: 'NO_SUCH_APP', + id: 'fcab192a-2c5a-43b7-8ad8-9b7054d8d40d', + }, + + noSuchSession: { + message: 'No such session.', + code: 'NO_SUCH_SESSION', + id: '5b5a1503-8bc8-4bd0-8054-dc189e8cdcb3', + }, + + pendingSession: { + message: 'This session is not completed yet.', + code: 'PENDING_SESSION', + id: '8c8a4145-02cc-4cca-8e66-29ba60445a8e', + }, + }, + + defines: [{ + req: { + type: 'object', + properties: { + appSecret: { type: 'string' }, + token: { type: 'string' }, + }, + required: ['appSecret', 'token'], + }, + res: { + type: 'object', + properties: { + accessToken: { type: 'string' }, + user: { + $ref: 'https://misskey-hub.net/api/schemas/UserDetailedNotMe', + } + }, + required: ['accessToken', 'user'], + } + }], + }, //#endregion } as const satisfies { [x: string]: IEndpointMeta; }; diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts index d71731cf5..0bf1d0147 100644 --- a/packages/misskey-js/src/entities.ts +++ b/packages/misskey-js/src/entities.ts @@ -119,11 +119,7 @@ export type Stats = { driveUsageRemote: number; }; -export type AuthSession = { - id: ID; - app: App; - token: string; -}; +export type AuthSession = Serialized>; export type FollowRequest = { id: ID; diff --git a/packages/misskey-js/src/schemas.ts b/packages/misskey-js/src/schemas.ts index e7699fc2a..759bcd736 100644 --- a/packages/misskey-js/src/schemas.ts +++ b/packages/misskey-js/src/schemas.ts @@ -56,6 +56,7 @@ import { SignInSchema, } from './schemas/sign-in.js'; import { packedModerationLogSchema } from './schemas/moderation-log.js'; +import { packedAuthSessionSchema } from './schemas/auth-session.js'; import { Error, ApiError } from './schemas/error.js'; import type { JSONSchema7, JSONSchema7Definition, GetDef, GetRefs, GetKeys, UnionToArray } from 'schema-type'; @@ -109,6 +110,7 @@ export const refs = { ServerInfoAdmin: ServerInfoAdminSchema, ModerationLog: packedModerationLogSchema, SignIn: SignInSchema, + AuthSession: packedAuthSessionSchema, Error: Error, ApiError: ApiError, diff --git a/packages/misskey-js/src/schemas/auth-session.ts b/packages/misskey-js/src/schemas/auth-session.ts new file mode 100644 index 000000000..da6774052 --- /dev/null +++ b/packages/misskey-js/src/schemas/auth-session.ts @@ -0,0 +1,19 @@ +import type { JSONSchema7Definition } from 'schema-type'; + +export const packedAuthSessionSchema = { + $id: 'https://misskey-hub.net/api/schemas/AuthSession', + + type: 'object', + properties: { + id: { $ref: 'https://misskey-hub.net/api/schemas/Id' }, + app: { $ref: 'https://misskey-hub.net/api/schemas/App' }, + token: { + type: 'string', + }, + }, + required: [ + 'id', + 'app', + 'token', + ], +} as const satisfies JSONSchema7Definition; diff --git a/packages/misskey-js/test-d/schemas.ts b/packages/misskey-js/test-d/schemas.ts index 444f04a8a..974d9d04e 100644 --- a/packages/misskey-js/test-d/schemas.ts +++ b/packages/misskey-js/test-d/schemas.ts @@ -1,3 +1,4 @@ +import { test } from 'node:test'; import { Packed, Def } from '../src/schemas'; import { expectType } from 'tsd'; @@ -122,6 +123,9 @@ describe('schemas', () => { test('moderation log', () => { type ModerationLog = Packed<'ModerationLog'>; }); + test('auth session', () => { + type AuthSession = Packed<'AuthSession'>; + }); test('error', () => { type Error = Packed<'Error'>; type ApiError = Packed<'ApiError'>;