mirror of
https://activitypub.software/TransFem-org/Sharkey
synced 2024-11-25 23:45:13 +00:00
wip
This commit is contained in:
parent
f651ca4b48
commit
35b1f73b51
9 changed files with 149 additions and 151 deletions
|
@ -6,6 +6,7 @@ import type { AuthSession } from '@/models/entities/AuthSession.js';
|
||||||
import type { User } from '@/models/entities/User.js';
|
import type { User } from '@/models/entities/User.js';
|
||||||
import { AppEntityService } from './AppEntityService.js';
|
import { AppEntityService } from './AppEntityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { Packed } from 'misskey-js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthSessionEntityService {
|
export class AuthSessionEntityService {
|
||||||
|
@ -21,7 +22,7 @@ export class AuthSessionEntityService {
|
||||||
public async pack(
|
public async pack(
|
||||||
src: AuthSession['id'] | AuthSession,
|
src: AuthSession['id'] | AuthSession,
|
||||||
me?: { id: User['id'] } | null | undefined,
|
me?: { id: User['id'] } | null | undefined,
|
||||||
) {
|
): Promise<Packed<'AuthSession'>> {
|
||||||
const session = typeof src === 'object' ? src : await this.authSessionsRepository.findOneByOrFail({ id: src });
|
const session = typeof src === 'object' ? src : await this.authSessionsRepository.findOneByOrFail({ id: src });
|
||||||
|
|
||||||
return await awaitAll({
|
return await awaitAll({
|
||||||
|
|
|
@ -7,47 +7,10 @@ import type { Config } from '@/config.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../../error.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
|
// eslint-disable-next-line import/no-default-export
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
export default class extends Endpoint<'auth/session/genrate'> {
|
||||||
|
name = 'auth/session/genrate' as const;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.config)
|
@Inject(DI.config)
|
||||||
private config: Config,
|
private config: Config,
|
||||||
|
@ -60,14 +23,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
|
|
||||||
private idService: IdService,
|
private idService: IdService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(async (ps, me) => {
|
||||||
// Lookup app
|
// Lookup app
|
||||||
const app = await this.appsRepository.findOneBy({
|
const app = await this.appsRepository.findOneBy({
|
||||||
secret: ps.appSecret,
|
secret: ps.appSecret,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw new ApiError(meta.errors.noSuchApp);
|
throw new ApiError(this.meta.errors.noSuchApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate token
|
// Generate token
|
||||||
|
|
|
@ -5,66 +5,24 @@ import { AuthSessionEntityService } from '@/core/entities/AuthSessionEntityServi
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../../error.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
|
// eslint-disable-next-line import/no-default-export
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
export default class extends Endpoint<'auth/session/show'> {
|
||||||
|
name = 'auth/session/show' as const;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.authSessionsRepository)
|
@Inject(DI.authSessionsRepository)
|
||||||
private authSessionsRepository: AuthSessionsRepository,
|
private authSessionsRepository: AuthSessionsRepository,
|
||||||
|
|
||||||
private authSessionEntityService: AuthSessionEntityService,
|
private authSessionEntityService: AuthSessionEntityService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(async (ps, me) => {
|
||||||
// Lookup session
|
// Lookup session
|
||||||
const session = await this.authSessionsRepository.findOneBy({
|
const session = await this.authSessionsRepository.findOneBy({
|
||||||
token: ps.token,
|
token: ps.token,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
throw new ApiError(meta.errors.noSuchSession);
|
throw new ApiError(this.meta.errors.noSuchSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.authSessionEntityService.pack(session, me);
|
return await this.authSessionEntityService.pack(session, me);
|
||||||
|
|
|
@ -5,61 +5,10 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { ApiError } from '../../../error.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
|
// eslint-disable-next-line import/no-default-export
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
|
export default class extends Endpoint<'auth/session/userkey'> {
|
||||||
|
name = 'auth/session/userkey' as const;
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.usersRepository)
|
@Inject(DI.usersRepository)
|
||||||
private usersRepository: UsersRepository,
|
private usersRepository: UsersRepository,
|
||||||
|
@ -75,14 +24,14 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
|
|
||||||
private userEntityService: UserEntityService,
|
private userEntityService: UserEntityService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(async (ps, me) => {
|
||||||
// Lookup app
|
// Lookup app
|
||||||
const app = await this.appsRepository.findOneBy({
|
const app = await this.appsRepository.findOneBy({
|
||||||
secret: ps.appSecret,
|
secret: ps.appSecret,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (app == null) {
|
if (app == null) {
|
||||||
throw new ApiError(meta.errors.noSuchApp);
|
throw new ApiError(this.meta.errors.noSuchApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch token
|
// Fetch token
|
||||||
|
@ -92,11 +41,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
throw new ApiError(meta.errors.noSuchSession);
|
throw new ApiError(this.meta.errors.noSuchSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.userId == null) {
|
if (session.userId == null) {
|
||||||
throw new ApiError(meta.errors.pendingSession);
|
throw new ApiError(this.meta.errors.pendingSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup access token
|
// Lookup access token
|
||||||
|
|
|
@ -2341,7 +2341,113 @@ export const endpoints = {
|
||||||
$ref: 'https://misskey-hub.net/api/schemas/App',
|
$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
|
//#endregion
|
||||||
} as const satisfies { [x: string]: IEndpointMeta; };
|
} as const satisfies { [x: string]: IEndpointMeta; };
|
||||||
|
|
||||||
|
|
|
@ -119,11 +119,7 @@ export type Stats = {
|
||||||
driveUsageRemote: number;
|
driveUsageRemote: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AuthSession = {
|
export type AuthSession = Serialized<Packed<'AuthSession'>>;
|
||||||
id: ID;
|
|
||||||
app: App;
|
|
||||||
token: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FollowRequest = {
|
export type FollowRequest = {
|
||||||
id: ID;
|
id: ID;
|
||||||
|
|
|
@ -56,6 +56,7 @@ import {
|
||||||
SignInSchema,
|
SignInSchema,
|
||||||
} from './schemas/sign-in.js';
|
} from './schemas/sign-in.js';
|
||||||
import { packedModerationLogSchema } from './schemas/moderation-log.js';
|
import { packedModerationLogSchema } from './schemas/moderation-log.js';
|
||||||
|
import { packedAuthSessionSchema } from './schemas/auth-session.js';
|
||||||
import { Error, ApiError } from './schemas/error.js';
|
import { Error, ApiError } from './schemas/error.js';
|
||||||
import type { JSONSchema7, JSONSchema7Definition, GetDef, GetRefs, GetKeys, UnionToArray } from 'schema-type';
|
import type { JSONSchema7, JSONSchema7Definition, GetDef, GetRefs, GetKeys, UnionToArray } from 'schema-type';
|
||||||
|
|
||||||
|
@ -109,6 +110,7 @@ export const refs = {
|
||||||
ServerInfoAdmin: ServerInfoAdminSchema,
|
ServerInfoAdmin: ServerInfoAdminSchema,
|
||||||
ModerationLog: packedModerationLogSchema,
|
ModerationLog: packedModerationLogSchema,
|
||||||
SignIn: SignInSchema,
|
SignIn: SignInSchema,
|
||||||
|
AuthSession: packedAuthSessionSchema,
|
||||||
|
|
||||||
Error: Error,
|
Error: Error,
|
||||||
ApiError: ApiError,
|
ApiError: ApiError,
|
||||||
|
|
19
packages/misskey-js/src/schemas/auth-session.ts
Normal file
19
packages/misskey-js/src/schemas/auth-session.ts
Normal file
|
@ -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;
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { test } from 'node:test';
|
||||||
import { Packed, Def } from '../src/schemas';
|
import { Packed, Def } from '../src/schemas';
|
||||||
import { expectType } from 'tsd';
|
import { expectType } from 'tsd';
|
||||||
|
|
||||||
|
@ -122,6 +123,9 @@ describe('schemas', () => {
|
||||||
test('moderation log', () => {
|
test('moderation log', () => {
|
||||||
type ModerationLog = Packed<'ModerationLog'>;
|
type ModerationLog = Packed<'ModerationLog'>;
|
||||||
});
|
});
|
||||||
|
test('auth session', () => {
|
||||||
|
type AuthSession = Packed<'AuthSession'>;
|
||||||
|
});
|
||||||
test('error', () => {
|
test('error', () => {
|
||||||
type Error = Packed<'Error'>;
|
type Error = Packed<'Error'>;
|
||||||
type ApiError = Packed<'ApiError'>;
|
type ApiError = Packed<'ApiError'>;
|
||||||
|
|
Loading…
Reference in a new issue