mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-19 05:55:34 +09:00
fix(api): raise coded errors for prerequisites and bounds (#2502)
This commit is contained in:
1 parent
f06d65db54
commit
cc110b9f5a
7 files changed
+109
-28
No files matched your search
@@ -16,6 +16,7 @@ import {PhoneVerificationRequiredError} from '@fluxer/errors/src/domains/auth/Ph
|
||||
import {SmsVerificationUnavailableError} from '@fluxer/errors/src/domains/auth/SmsVerificationUnavailableError';
|
||||
import {CaptchaVerificationRequiredError} from '@fluxer/errors/src/domains/core/CaptchaVerificationRequiredError';
|
||||
import {RateLimitError} from '@fluxer/errors/src/domains/core/RateLimitError';
|
||||
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
|
||||
import type {FluxerError} from '@fluxer/errors/src/FluxerError';
|
||||
import {PHONE_E164_REGEX} from '@fluxer/schema/src/primitives/UserValidators';
|
||||
import type {RateLimitResult, RateLimitScope} from '@pkgs/rate_limit/src/IRateLimitService';
|
||||
@@ -74,15 +75,16 @@ function reuseStoreFor(ctx: ApiContext): PhoneVerificationReuseStore {
|
||||
|
||||
export async function startInboundPhoneChallenge(ctx: ApiContext, userId: UserID): Promise<IssuedChallenge> {
|
||||
const {inboundSmsChallenge, users, config} = ctx.services;
|
||||
if (!inboundSmsChallenge) {
|
||||
throw new Error('Inbound SMS challenge flow is not configured on this instance');
|
||||
}
|
||||
const ourNumber = config.sms.inboundChallengeNumber;
|
||||
if (!ourNumber) {
|
||||
throw new Error('Config.sms.inboundChallengeNumber is required for the inbound SMS challenge flow');
|
||||
if (!inboundSmsChallenge || !ourNumber) {
|
||||
Logger.warn(
|
||||
{userId: String(userId)},
|
||||
'Inbound SMS challenge requested but FLUXER_SMS_INBOUND_CHALLENGE_NUMBER is unset',
|
||||
);
|
||||
throw new SmsVerificationUnavailableError();
|
||||
}
|
||||
const user = await users.findUnique(userId);
|
||||
if (!user) throw new Error('User not found');
|
||||
if (!user) throw new UnknownUserError();
|
||||
assertNonBotUser(user);
|
||||
return inboundSmsChallenge.issueChallenge({userId, ourNumber});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {afterAll, beforeAll, beforeEach, describe, expect, it} from 'vitest';
|
||||
import {getConfig} from '../../Config';
|
||||
import type {ApiTestHarness} from '../../test/ApiTestHarness';
|
||||
import {createBuilder} from '../../test/TestRequestBuilder';
|
||||
import {createAuthHarness, createTestAccount} from './AuthTestUtils';
|
||||
|
||||
describe('Inbound SMS challenge without a receiving number', () => {
|
||||
let harness: ApiTestHarness;
|
||||
beforeAll(async () => {
|
||||
harness = await createAuthHarness();
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await harness.reset();
|
||||
});
|
||||
afterAll(async () => {
|
||||
await harness?.shutdown();
|
||||
});
|
||||
it('rejects the challenge with SMS_VERIFICATION_UNAVAILABLE when no number is configured', async () => {
|
||||
const account = await createTestAccount(harness);
|
||||
const config = getConfig();
|
||||
const previousInboundNumber = config.sms.inboundChallengeNumber;
|
||||
config.sms.inboundChallengeNumber = undefined;
|
||||
try {
|
||||
const {response, json} = await createBuilder(harness, account.token)
|
||||
.post('/users/@me/phone/inbound-challenge')
|
||||
.executeRaw();
|
||||
expect(response.status).toBe(400);
|
||||
expect(json).toMatchObject({code: 'SMS_VERIFICATION_UNAVAILABLE'});
|
||||
} finally {
|
||||
config.sms.inboundChallengeNumber = previousInboundNumber;
|
||||
}
|
||||
});
|
||||
it('issues the challenge once a receiving number is configured', async () => {
|
||||
const account = await createTestAccount(harness);
|
||||
const config = getConfig();
|
||||
const previousInboundNumber = config.sms.inboundChallengeNumber;
|
||||
config.sms.inboundChallengeNumber = '+15551234567';
|
||||
try {
|
||||
const response = await createBuilder<{
|
||||
challenge_code: string;
|
||||
our_number: string;
|
||||
expires_at: string;
|
||||
}>(harness, account.token)
|
||||
.post('/users/@me/phone/inbound-challenge')
|
||||
.expect(200)
|
||||
.execute();
|
||||
expect(response.our_number).toBe('+15551234567');
|
||||
expect(response.challenge_code).toMatch(/^\d{6}$/);
|
||||
} finally {
|
||||
config.sms.inboundChallengeNumber = previousInboundNumber;
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user