/signin -> /signin-flow
This commit is contained in:
parent
b190ff7742
commit
73e063bcb7
|
@ -120,7 +120,7 @@ describe('After user signup', () => {
|
||||||
it('signin', () => {
|
it('signin', () => {
|
||||||
cy.visitHome();
|
cy.visitHome();
|
||||||
|
|
||||||
cy.intercept('POST', '/api/signin').as('signin');
|
cy.intercept('POST', '/api/signin-flow').as('signin');
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
cy.get('[data-cy-signin]').click();
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ Cypress.Commands.add('registerUser', (username, password, isAdmin = false) => {
|
||||||
Cypress.Commands.add('login', (username, password) => {
|
Cypress.Commands.add('login', (username, password) => {
|
||||||
cy.visitHome();
|
cy.visitHome();
|
||||||
|
|
||||||
cy.intercept('POST', '/api/signin').as('signin');
|
cy.intercept('POST', '/api/signin-flow').as('signin');
|
||||||
|
|
||||||
cy.get('[data-cy-signin]').click();
|
cy.get('[data-cy-signin]').click();
|
||||||
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
cy.get('[data-cy-signin-page-input]').should('be.visible', { timeout: 1000 });
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { ApiLoggerService } from './api/ApiLoggerService.js';
|
||||||
import { ApiServerService } from './api/ApiServerService.js';
|
import { ApiServerService } from './api/ApiServerService.js';
|
||||||
import { AuthenticateService } from './api/AuthenticateService.js';
|
import { AuthenticateService } from './api/AuthenticateService.js';
|
||||||
import { RateLimiterService } from './api/RateLimiterService.js';
|
import { RateLimiterService } from './api/RateLimiterService.js';
|
||||||
import { SigninApiService } from './api/SigninApiService.js';
|
import { SigninFlowApiService } from './api/SigninFlowApiService.js';
|
||||||
import { SigninService } from './api/SigninService.js';
|
import { SigninService } from './api/SigninService.js';
|
||||||
import { SignupApiService } from './api/SignupApiService.js';
|
import { SignupApiService } from './api/SignupApiService.js';
|
||||||
import { StreamingApiServerService } from './api/StreamingApiServerService.js';
|
import { StreamingApiServerService } from './api/StreamingApiServerService.js';
|
||||||
|
@ -71,7 +71,7 @@ import { SigninWithPasskeyApiService } from './api/SigninWithPasskeyApiService.j
|
||||||
ApiServerService,
|
ApiServerService,
|
||||||
AuthenticateService,
|
AuthenticateService,
|
||||||
RateLimiterService,
|
RateLimiterService,
|
||||||
SigninApiService,
|
SigninFlowApiService,
|
||||||
SigninWithPasskeyApiService,
|
SigninWithPasskeyApiService,
|
||||||
SigninService,
|
SigninService,
|
||||||
SignupApiService,
|
SignupApiService,
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { bindThis } from '@/decorators.js';
|
||||||
import endpoints from './endpoints.js';
|
import endpoints from './endpoints.js';
|
||||||
import { ApiCallService } from './ApiCallService.js';
|
import { ApiCallService } from './ApiCallService.js';
|
||||||
import { SignupApiService } from './SignupApiService.js';
|
import { SignupApiService } from './SignupApiService.js';
|
||||||
import { SigninApiService } from './SigninApiService.js';
|
import { SigninFlowApiService } from './SigninFlowApiService.js';
|
||||||
import { SigninWithPasskeyApiService } from './SigninWithPasskeyApiService.js';
|
import { SigninWithPasskeyApiService } from './SigninWithPasskeyApiService.js';
|
||||||
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
|
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export class ApiServerService {
|
||||||
private userEntityService: UserEntityService,
|
private userEntityService: UserEntityService,
|
||||||
private apiCallService: ApiCallService,
|
private apiCallService: ApiCallService,
|
||||||
private signupApiService: SignupApiService,
|
private signupApiService: SignupApiService,
|
||||||
private signinApiService: SigninApiService,
|
private signinFlowApiService: SigninFlowApiService,
|
||||||
private signinWithPasskeyApiService: SigninWithPasskeyApiService,
|
private signinWithPasskeyApiService: SigninWithPasskeyApiService,
|
||||||
) {
|
) {
|
||||||
//this.createServer = this.createServer.bind(this);
|
//this.createServer = this.createServer.bind(this);
|
||||||
|
@ -133,7 +133,7 @@ export class ApiServerService {
|
||||||
'turnstile-response'?: string;
|
'turnstile-response'?: string;
|
||||||
'm-captcha-response'?: string;
|
'm-captcha-response'?: string;
|
||||||
};
|
};
|
||||||
}>('/signin', (request, reply) => this.signinApiService.signin(request, reply));
|
}>('/signin-flow', (request, reply) => this.signinFlowApiService.signin(request, reply));
|
||||||
|
|
||||||
fastify.post<{
|
fastify.post<{
|
||||||
Body: {
|
Body: {
|
||||||
|
|
|
@ -30,7 +30,7 @@ import type { AuthenticationResponseJSON } from '@simplewebauthn/types';
|
||||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SigninApiService {
|
export class SigninFlowApiService {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.config)
|
@Inject(DI.config)
|
||||||
private config: Config,
|
private config: Config,
|
|
@ -196,7 +196,7 @@ describe('2要素認証', () => {
|
||||||
}, alice);
|
}, alice);
|
||||||
assert.strictEqual(doneResponse.status, 200);
|
assert.strictEqual(doneResponse.status, 200);
|
||||||
|
|
||||||
const signinWithoutTokenResponse = await api('signin', {
|
const signinWithoutTokenResponse = await api('signin-flow', {
|
||||||
...signinParam(),
|
...signinParam(),
|
||||||
});
|
});
|
||||||
assert.strictEqual(signinWithoutTokenResponse.status, 200);
|
assert.strictEqual(signinWithoutTokenResponse.status, 200);
|
||||||
|
@ -205,7 +205,7 @@ describe('2要素認証', () => {
|
||||||
next: 'totp',
|
next: 'totp',
|
||||||
});
|
});
|
||||||
|
|
||||||
const signinResponse = await api('signin', {
|
const signinResponse = await api('signin-flow', {
|
||||||
...signinParam(),
|
...signinParam(),
|
||||||
token: otpToken(registerResponse.body.secret),
|
token: otpToken(registerResponse.body.secret),
|
||||||
});
|
});
|
||||||
|
@ -251,7 +251,7 @@ describe('2要素認証', () => {
|
||||||
assert.strictEqual(keyDoneResponse.body.id, credentialId.toString('base64url'));
|
assert.strictEqual(keyDoneResponse.body.id, credentialId.toString('base64url'));
|
||||||
assert.strictEqual(keyDoneResponse.body.name, keyName);
|
assert.strictEqual(keyDoneResponse.body.name, keyName);
|
||||||
|
|
||||||
const signinResponse = await api('signin', {
|
const signinResponse = await api('signin-flow', {
|
||||||
...signinParam(),
|
...signinParam(),
|
||||||
});
|
});
|
||||||
assert.strictEqual(signinResponse.status, 200);
|
assert.strictEqual(signinResponse.status, 200);
|
||||||
|
@ -261,7 +261,7 @@ describe('2要素認証', () => {
|
||||||
assert.notEqual(signinResponse.body.authRequest.allowCredentials, undefined);
|
assert.notEqual(signinResponse.body.authRequest.allowCredentials, undefined);
|
||||||
assert.strictEqual(signinResponse.body.authRequest.allowCredentials && signinResponse.body.authRequest.allowCredentials[0]?.id, credentialId.toString('base64url'));
|
assert.strictEqual(signinResponse.body.authRequest.allowCredentials && signinResponse.body.authRequest.allowCredentials[0]?.id, credentialId.toString('base64url'));
|
||||||
|
|
||||||
const signinResponse2 = await api('signin', signinWithSecurityKeyParam({
|
const signinResponse2 = await api('signin-flow', signinWithSecurityKeyParam({
|
||||||
keyName,
|
keyName,
|
||||||
credentialId,
|
credentialId,
|
||||||
requestOptions: signinResponse.body.authRequest,
|
requestOptions: signinResponse.body.authRequest,
|
||||||
|
@ -313,7 +313,7 @@ describe('2要素認証', () => {
|
||||||
assert.strictEqual(iResponse.status, 200);
|
assert.strictEqual(iResponse.status, 200);
|
||||||
assert.strictEqual(iResponse.body.usePasswordLessLogin, true);
|
assert.strictEqual(iResponse.body.usePasswordLessLogin, true);
|
||||||
|
|
||||||
const signinResponse = await api('signin', {
|
const signinResponse = await api('signin-flow', {
|
||||||
...signinParam(),
|
...signinParam(),
|
||||||
password: '',
|
password: '',
|
||||||
});
|
});
|
||||||
|
@ -323,7 +323,7 @@ describe('2要素認証', () => {
|
||||||
assert.notEqual(signinResponse.body.authRequest.challenge, undefined);
|
assert.notEqual(signinResponse.body.authRequest.challenge, undefined);
|
||||||
assert.notEqual(signinResponse.body.authRequest.allowCredentials, undefined);
|
assert.notEqual(signinResponse.body.authRequest.allowCredentials, undefined);
|
||||||
|
|
||||||
const signinResponse2 = await api('signin', {
|
const signinResponse2 = await api('signin-flow', {
|
||||||
...signinWithSecurityKeyParam({
|
...signinWithSecurityKeyParam({
|
||||||
keyName,
|
keyName,
|
||||||
credentialId,
|
credentialId,
|
||||||
|
@ -437,7 +437,7 @@ describe('2要素認証', () => {
|
||||||
assert.strictEqual(afterIResponse.status, 200);
|
assert.strictEqual(afterIResponse.status, 200);
|
||||||
assert.strictEqual(afterIResponse.body.securityKeys, false);
|
assert.strictEqual(afterIResponse.body.securityKeys, false);
|
||||||
|
|
||||||
const signinResponse = await api('signin', {
|
const signinResponse = await api('signin-flow', {
|
||||||
...signinParam(),
|
...signinParam(),
|
||||||
token: otpToken(registerResponse.body.secret),
|
token: otpToken(registerResponse.body.secret),
|
||||||
});
|
});
|
||||||
|
@ -473,7 +473,7 @@ describe('2要素認証', () => {
|
||||||
}, alice);
|
}, alice);
|
||||||
assert.strictEqual(unregisterResponse.status, 204);
|
assert.strictEqual(unregisterResponse.status, 204);
|
||||||
|
|
||||||
const signinResponse = await api('signin', {
|
const signinResponse = await api('signin-flow', {
|
||||||
...signinParam(),
|
...signinParam(),
|
||||||
});
|
});
|
||||||
assert.strictEqual(signinResponse.status, 200);
|
assert.strictEqual(signinResponse.status, 200);
|
||||||
|
|
|
@ -66,9 +66,9 @@ describe('Endpoints', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('signin', () => {
|
describe('signin-flow', () => {
|
||||||
test('間違ったパスワードでサインインできない', async () => {
|
test('間違ったパスワードでサインインできない', async () => {
|
||||||
const res = await api('signin', {
|
const res = await api('signin-flow', {
|
||||||
username: 'test1',
|
username: 'test1',
|
||||||
password: 'bar',
|
password: 'bar',
|
||||||
});
|
});
|
||||||
|
@ -77,7 +77,7 @@ describe('Endpoints', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('クエリをインジェクションできない', async () => {
|
test('クエリをインジェクションできない', async () => {
|
||||||
const res = await api('signin', {
|
const res = await api('signin-flow', {
|
||||||
username: 'test1',
|
username: 'test1',
|
||||||
// @ts-expect-error password must be string
|
// @ts-expect-error password must be string
|
||||||
password: {
|
password: {
|
||||||
|
@ -89,7 +89,7 @@ describe('Endpoints', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('正しい情報でサインインできる', async () => {
|
test('正しい情報でサインインできる', async () => {
|
||||||
const res = await api('signin', {
|
const res = await api('signin-flow', {
|
||||||
username: 'test1',
|
username: 'test1',
|
||||||
password: 'test1',
|
password: 'test1',
|
||||||
});
|
});
|
||||||
|
|
|
@ -226,7 +226,7 @@ async function tryLogin(req: Partial<Misskey.entities.SigninRequest>): Promise<M
|
||||||
throw new Error('Invalid request');
|
throw new Error('Invalid request');
|
||||||
}
|
}
|
||||||
|
|
||||||
return await misskeyApi('signin', _req).then(async (res) => {
|
return await misskeyApi('signin-flow', _req).then(async (res) => {
|
||||||
if (res.finished) {
|
if (res.finished) {
|
||||||
emit('login', res);
|
emit('login', res);
|
||||||
await onLoginSucceeded(res);
|
await onLoginSucceeded(res);
|
||||||
|
|
|
@ -269,7 +269,7 @@ async function onSubmit(): Promise<void> {
|
||||||
});
|
});
|
||||||
emit('signupEmailPending');
|
emit('signupEmailPending');
|
||||||
} else {
|
} else {
|
||||||
const res = await misskeyApi('signin', {
|
const res = await misskeyApi('signin-flow', {
|
||||||
username: username.value,
|
username: username.value,
|
||||||
password: password.value,
|
password: password.value,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1158,9 +1158,9 @@ export type Endpoints = Overwrite<Endpoints_2, {
|
||||||
req: SignupPendingRequest;
|
req: SignupPendingRequest;
|
||||||
res: SignupPendingResponse;
|
res: SignupPendingResponse;
|
||||||
};
|
};
|
||||||
'signin': {
|
'signin-flow': {
|
||||||
req: SigninRequest;
|
req: SigninFlowRequest;
|
||||||
res: SigninResponse;
|
res: SigninFlowResponse;
|
||||||
};
|
};
|
||||||
'signin-with-passkey': {
|
'signin-with-passkey': {
|
||||||
req: SigninWithPasskeyRequest;
|
req: SigninWithPasskeyRequest;
|
||||||
|
@ -1208,11 +1208,11 @@ declare namespace entities {
|
||||||
SignupResponse,
|
SignupResponse,
|
||||||
SignupPendingRequest,
|
SignupPendingRequest,
|
||||||
SignupPendingResponse,
|
SignupPendingResponse,
|
||||||
SigninRequest,
|
SigninFlowRequest,
|
||||||
|
SigninFlowResponse,
|
||||||
SigninWithPasskeyRequest,
|
SigninWithPasskeyRequest,
|
||||||
SigninWithPasskeyInitResponse,
|
SigninWithPasskeyInitResponse,
|
||||||
SigninWithPasskeyResponse,
|
SigninWithPasskeyResponse,
|
||||||
SigninResponse,
|
|
||||||
PartialRolePolicyOverride,
|
PartialRolePolicyOverride,
|
||||||
EmptyRequest,
|
EmptyRequest,
|
||||||
EmptyResponse,
|
EmptyResponse,
|
||||||
|
@ -3038,7 +3038,7 @@ type ServerStatsLog = ServerStats[];
|
||||||
type Signin = components['schemas']['Signin'];
|
type Signin = components['schemas']['Signin'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type SigninRequest = {
|
type SigninFlowRequest = {
|
||||||
username: string;
|
username: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
|
@ -3050,7 +3050,7 @@ type SigninRequest = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type SigninResponse = {
|
type SigninFlowResponse = {
|
||||||
finished: true;
|
finished: true;
|
||||||
id: User['id'];
|
id: User['id'];
|
||||||
i: string;
|
i: string;
|
||||||
|
@ -3077,7 +3077,7 @@ type SigninWithPasskeyRequest = {
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type SigninWithPasskeyResponse = {
|
type SigninWithPasskeyResponse = {
|
||||||
signinResponse: SigninResponse;
|
signinResponse: SigninFlowResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
|
|
|
@ -3,8 +3,8 @@ import { UserDetailed } from './autogen/models.js';
|
||||||
import { AdminRolesCreateRequest, AdminRolesCreateResponse, UsersShowRequest } from './autogen/entities.js';
|
import { AdminRolesCreateRequest, AdminRolesCreateResponse, UsersShowRequest } from './autogen/entities.js';
|
||||||
import {
|
import {
|
||||||
PartialRolePolicyOverride,
|
PartialRolePolicyOverride,
|
||||||
SigninRequest,
|
SigninFlowRequest,
|
||||||
SigninResponse,
|
SigninFlowResponse,
|
||||||
SigninWithPasskeyInitResponse,
|
SigninWithPasskeyInitResponse,
|
||||||
SigninWithPasskeyRequest,
|
SigninWithPasskeyRequest,
|
||||||
SigninWithPasskeyResponse,
|
SigninWithPasskeyResponse,
|
||||||
|
@ -81,9 +81,9 @@ export type Endpoints = Overwrite<
|
||||||
res: SignupPendingResponse;
|
res: SignupPendingResponse;
|
||||||
},
|
},
|
||||||
// api.jsonには載せないものなのでここで定義
|
// api.jsonには載せないものなのでここで定義
|
||||||
'signin': {
|
'signin-flow': {
|
||||||
req: SigninRequest;
|
req: SigninFlowRequest;
|
||||||
res: SigninResponse;
|
res: SigninFlowResponse;
|
||||||
},
|
},
|
||||||
'signin-with-passkey': {
|
'signin-with-passkey': {
|
||||||
req: SigninWithPasskeyRequest;
|
req: SigninWithPasskeyRequest;
|
||||||
|
|
|
@ -267,7 +267,7 @@ export type SignupPendingResponse = {
|
||||||
i: string,
|
i: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SigninRequest = {
|
export type SigninFlowRequest = {
|
||||||
username: string;
|
username: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
|
@ -278,6 +278,19 @@ export type SigninRequest = {
|
||||||
'm-captcha-response'?: string | null;
|
'm-captcha-response'?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SigninFlowResponse = {
|
||||||
|
finished: true;
|
||||||
|
id: User['id'];
|
||||||
|
i: string;
|
||||||
|
} | {
|
||||||
|
finished: false;
|
||||||
|
next: 'captcha' | 'password' | 'totp';
|
||||||
|
} | {
|
||||||
|
finished: false;
|
||||||
|
next: 'passkey';
|
||||||
|
authRequest: PublicKeyCredentialRequestOptionsJSON;
|
||||||
|
};
|
||||||
|
|
||||||
export type SigninWithPasskeyRequest = {
|
export type SigninWithPasskeyRequest = {
|
||||||
credential?: AuthenticationResponseJSON;
|
credential?: AuthenticationResponseJSON;
|
||||||
context?: string;
|
context?: string;
|
||||||
|
@ -289,20 +302,7 @@ export type SigninWithPasskeyInitResponse = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SigninWithPasskeyResponse = {
|
export type SigninWithPasskeyResponse = {
|
||||||
signinResponse: SigninResponse;
|
signinResponse: SigninFlowResponse;
|
||||||
};
|
|
||||||
|
|
||||||
export type SigninResponse = {
|
|
||||||
finished: true;
|
|
||||||
id: User['id'];
|
|
||||||
i: string;
|
|
||||||
} | {
|
|
||||||
finished: false;
|
|
||||||
next: 'captcha' | 'password' | 'totp';
|
|
||||||
} | {
|
|
||||||
finished: false;
|
|
||||||
next: 'passkey';
|
|
||||||
authRequest: PublicKeyCredentialRequestOptionsJSON;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type Values<T extends Record<PropertyKey, unknown>> = T[keyof T];
|
type Values<T extends Record<PropertyKey, unknown>> = T[keyof T];
|
||||||
|
|
Loading…
Reference in New Issue