Compare commits
6 Commits
33b08cb80b
...
aa7c27c49d
Author | SHA1 | Date |
---|---|---|
かっこかり | aa7c27c49d | |
かっこかり | 50e4ad9cf1 | |
かっこかり | 6219be759f | |
kakkokari-gtyih | 95f00b08c0 | |
kakkokari-gtyih | 401094b6b2 | |
kakkokari-gtyih | 9ee5465427 |
|
@ -11,6 +11,7 @@
|
||||||
- Fix: お知らせ作成時に画像URL入力欄を空欄に変更できないのを修正 ( #14976 )
|
- Fix: お知らせ作成時に画像URL入力欄を空欄に変更できないのを修正 ( #14976 )
|
||||||
- Enhance: 依存関係の更新
|
- Enhance: 依存関係の更新
|
||||||
- Enhance: l10nの更新
|
- Enhance: l10nの更新
|
||||||
|
- Enhance: 登録時の処理のエラーの内容を詳細に表示するように
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
- Enhance: Bull DashboardでRelationship Queueの状態も確認できるように
|
- Enhance: Bull DashboardでRelationship Queueの状態も確認できるように
|
||||||
|
|
|
@ -7164,6 +7164,36 @@ export interface Locale extends ILocale {
|
||||||
* 入力されたメールアドレス({email})宛に確認のメールが送信されました。メールに記載されたリンクにアクセスすると、アカウントの作成が完了します。メールに記載されているリンクの有効期限は30分です。
|
* 入力されたメールアドレス({email})宛に確認のメールが送信されました。メールに記載されたリンクにアクセスすると、アカウントの作成が完了します。メールに記載されているリンクの有効期限は30分です。
|
||||||
*/
|
*/
|
||||||
"emailSent": ParameterizedString<"email">;
|
"emailSent": ParameterizedString<"email">;
|
||||||
|
"_errors": {
|
||||||
|
/**
|
||||||
|
* メールアドレスが入力されていないか、不正な値です。
|
||||||
|
*/
|
||||||
|
"emailInvalid": string;
|
||||||
|
/**
|
||||||
|
* このメールアドレスを使用して登録することはできません。
|
||||||
|
*/
|
||||||
|
"emailNotAllowed": string;
|
||||||
|
/**
|
||||||
|
* 招待コードが入力されていないか、不正な値です。
|
||||||
|
*/
|
||||||
|
"invitationCodeInvalid": string;
|
||||||
|
/**
|
||||||
|
* 招待コードが見つからなかったか、既に使用されています。
|
||||||
|
*/
|
||||||
|
"invitationCodeNotFoundOrUsed": string;
|
||||||
|
/**
|
||||||
|
* 招待コードの有効期限が切れています。
|
||||||
|
*/
|
||||||
|
"invitationCodeExpired": string;
|
||||||
|
/**
|
||||||
|
* このユーザー名は既に使用されています。
|
||||||
|
*/
|
||||||
|
"usernameAlreadyUsed": string;
|
||||||
|
/**
|
||||||
|
* このユーザー名で登録することはできません。
|
||||||
|
*/
|
||||||
|
"usernameNotAllowed": string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
"_accountDelete": {
|
"_accountDelete": {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1856,6 +1856,14 @@ _signup:
|
||||||
almostThere: "ほとんど完了です"
|
almostThere: "ほとんど完了です"
|
||||||
emailAddressInfo: "あなたが使っているメールアドレスを入力してください。メールアドレスが公開されることはありません。"
|
emailAddressInfo: "あなたが使っているメールアドレスを入力してください。メールアドレスが公開されることはありません。"
|
||||||
emailSent: "入力されたメールアドレス({email})宛に確認のメールが送信されました。メールに記載されたリンクにアクセスすると、アカウントの作成が完了します。メールに記載されているリンクの有効期限は30分です。"
|
emailSent: "入力されたメールアドレス({email})宛に確認のメールが送信されました。メールに記載されたリンクにアクセスすると、アカウントの作成が完了します。メールに記載されているリンクの有効期限は30分です。"
|
||||||
|
_errors:
|
||||||
|
emailInvalid: "メールアドレスが入力されていないか、不正な値です。"
|
||||||
|
emailNotAllowed: "このメールアドレスを使用して登録することはできません。"
|
||||||
|
invitationCodeInvalid: "招待コードが入力されていないか、不正な値です。"
|
||||||
|
invitationCodeNotFoundOrUsed: "招待コードが見つからなかったか、既に使用されています。"
|
||||||
|
invitationCodeExpired: "招待コードの有効期限が切れています。"
|
||||||
|
usernameAlreadyUsed: "このユーザー名は既に使用されています。"
|
||||||
|
usernameNotAllowed: "このユーザー名で登録することはできません。"
|
||||||
|
|
||||||
_accountDelete:
|
_accountDelete:
|
||||||
accountDelete: "アカウントの削除"
|
accountDelete: "アカウントの削除"
|
||||||
|
|
|
@ -18,6 +18,7 @@ import generateUserToken from '@/misc/generate-native-user-token.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
import { InstanceActorService } from '@/core/InstanceActorService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import UsersChart from '@/core/chart/charts/users.js';
|
import UsersChart from '@/core/chart/charts/users.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { UserService } from '@/core/UserService.js';
|
import { UserService } from '@/core/UserService.js';
|
||||||
|
@ -59,13 +60,13 @@ export class SignupService {
|
||||||
|
|
||||||
// Validate username
|
// Validate username
|
||||||
if (!this.userEntityService.validateLocalUsername(username)) {
|
if (!this.userEntityService.validateLocalUsername(username)) {
|
||||||
throw new Error('INVALID_USERNAME');
|
throw new IdentifiableError('be85f7f4-1dd3-4107-bce4-07cdb0cbb0c3', 'INVALID_USERNAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password != null && passwordHash == null) {
|
if (password != null && passwordHash == null) {
|
||||||
// Validate password
|
// Validate password
|
||||||
if (!this.userEntityService.validatePassword(password)) {
|
if (!this.userEntityService.validatePassword(password)) {
|
||||||
throw new Error('INVALID_PASSWORD');
|
throw new IdentifiableError('d5f4959c-a881-41e8-b755-718fbf161258', 'INVALID_PASSWORD');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate hash of password
|
// Generate hash of password
|
||||||
|
@ -78,12 +79,12 @@ export class SignupService {
|
||||||
|
|
||||||
// Check username duplication
|
// Check username duplication
|
||||||
if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) {
|
if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) {
|
||||||
throw new Error('DUPLICATED_USERNAME');
|
throw new IdentifiableError('d412327a-1bd7-4b70-a982-7eec000db8fc', 'DUPLICATED_USERNAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check deleted username duplication
|
// Check deleted username duplication
|
||||||
if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) {
|
if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) {
|
||||||
throw new Error('USED_USERNAME');
|
throw new IdentifiableError('dd5f52be-2c95-4c39-ba45-dc2d74b3dd81', 'USED_USERNAME');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isTheFirstUser = !await this.instanceActorService.realLocalUsersPresent();
|
const isTheFirstUser = !await this.instanceActorService.realLocalUsersPresent();
|
||||||
|
@ -91,7 +92,7 @@ export class SignupService {
|
||||||
if (!opts.ignorePreservedUsernames && !isTheFirstUser) {
|
if (!opts.ignorePreservedUsernames && !isTheFirstUser) {
|
||||||
const isPreserved = this.meta.preservedUsernames.map(x => x.toLowerCase()).includes(username.toLowerCase());
|
const isPreserved = this.meta.preservedUsernames.map(x => x.toLowerCase()).includes(username.toLowerCase());
|
||||||
if (isPreserved) {
|
if (isPreserved) {
|
||||||
throw new Error('USED_USERNAME');
|
throw new IdentifiableError('adad138b-9c63-41bf-931e-6b050fd3bb8d', 'DENIED_USERNAME');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +122,9 @@ export class SignupService {
|
||||||
host: IsNull(),
|
host: IsNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exist) throw new Error(' the username is already used');
|
if (exist) {
|
||||||
|
throw new IdentifiableError('d412327a-1bd7-4b70-a982-7eec000db8fc', 'DUPLICATED_USERNAME');
|
||||||
|
}
|
||||||
|
|
||||||
account = await transactionalEntityManager.save(new MiUser({
|
account = await transactionalEntityManager.save(new MiUser({
|
||||||
id: this.idService.gen(),
|
id: this.idService.gen(),
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||||
import { EmailService } from '@/core/EmailService.js';
|
import { EmailService } from '@/core/EmailService.js';
|
||||||
import { MiLocalUser } from '@/models/User.js';
|
import { MiLocalUser } from '@/models/User.js';
|
||||||
import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
|
import { FastifyReplyError } from '@/misc/fastify-reply-error.js';
|
||||||
|
import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
import { L_CHARS, secureRndstr } from '@/misc/secure-rndstr.js';
|
||||||
import { SigninService } from './SigninService.js';
|
import { SigninService } from './SigninService.js';
|
||||||
|
@ -74,6 +75,11 @@ export class SignupApiService {
|
||||||
) {
|
) {
|
||||||
const body = request.body;
|
const body = request.body;
|
||||||
|
|
||||||
|
function error(status: number, error: { id: string, [x: string]: string }) {
|
||||||
|
reply.code(status);
|
||||||
|
return { error };
|
||||||
|
}
|
||||||
|
|
||||||
// Verify *Captcha
|
// Verify *Captcha
|
||||||
// ただしテスト時はこの機構は障害となるため無効にする
|
// ただしテスト時はこの機構は障害となるため無効にする
|
||||||
if (process.env.NODE_ENV !== 'test') {
|
if (process.env.NODE_ENV !== 'test') {
|
||||||
|
@ -115,24 +121,30 @@ export class SignupApiService {
|
||||||
const emailAddress = body['emailAddress'];
|
const emailAddress = body['emailAddress'];
|
||||||
|
|
||||||
if (this.meta.emailRequiredForSignup) {
|
if (this.meta.emailRequiredForSignup) {
|
||||||
if (emailAddress == null || typeof emailAddress !== 'string') {
|
if (emailAddress == null || typeof emailAddress !== 'string' || emailAddress === '') {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: '33b104c9-2f22-4640-b27a-40979bde4a77',
|
||||||
|
message: 'Email address is not present or is invalid.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await this.emailService.validateEmailForAccount(emailAddress);
|
const res = await this.emailService.validateEmailForAccount(emailAddress);
|
||||||
if (!res.available) {
|
if (!res.available) {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: '75ece55a-7869-49b1-b796-c0634224fcae',
|
||||||
|
message: 'You cannot use this email address.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ticket: MiRegistrationTicket | null = null;
|
let ticket: MiRegistrationTicket | null = null;
|
||||||
|
|
||||||
if (this.meta.disableRegistration) {
|
if (this.meta.disableRegistration) {
|
||||||
if (invitationCode == null || typeof invitationCode !== 'string') {
|
if (invitationCode == null || typeof invitationCode !== 'string' || invitationCode === '') {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: 'c8324ccf-7153-47a0-90a3-682eb06ba10d',
|
||||||
|
message: 'Invitation code is not present or is invalid.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ticket = await this.registrationTicketsRepository.findOneBy({
|
ticket = await this.registrationTicketsRepository.findOneBy({
|
||||||
|
@ -140,47 +152,69 @@ export class SignupApiService {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ticket == null || ticket.usedById != null) {
|
if (ticket == null || ticket.usedById != null) {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: 'f08118af-8358-441c-b992-b5b0bbd337d2',
|
||||||
|
message: 'Invitation code not found or already used.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ticket.expiresAt && ticket.expiresAt < new Date()) {
|
if (ticket.expiresAt && ticket.expiresAt < new Date()) {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: '3277822c-29dd-4bc9-ad57-47af702f78b8',
|
||||||
|
message: 'Invitation code has expired.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// メアド認証が有効の場合
|
// メアド認証が有効の場合
|
||||||
if (this.meta.emailRequiredForSignup) {
|
if (this.meta.emailRequiredForSignup) {
|
||||||
// メアド認証済みならエラー
|
// メアド認証済みならエラー
|
||||||
if (ticket.usedBy) {
|
if (ticket.usedBy) {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: 'f08118af-8358-441c-b992-b5b0bbd337d2',
|
||||||
|
message: 'Invitation code not found or already used.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 認証しておらず、メール送信から30分以内ならエラー
|
// 認証しておらず、メール送信から30分以内ならエラー
|
||||||
if (ticket.usedAt && ticket.usedAt.getTime() + (1000 * 60 * 30) > Date.now()) {
|
if (ticket.usedAt && ticket.usedAt.getTime() + (1000 * 60 * 30) > Date.now()) {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: 'f08118af-8358-441c-b992-b5b0bbd337d2',
|
||||||
|
message: 'Invitation code not found or already used.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (ticket.usedAt) {
|
} else if (ticket.usedAt) {
|
||||||
reply.code(400);
|
return error(400, {
|
||||||
return;
|
id: 'f08118af-8358-441c-b992-b5b0bbd337d2',
|
||||||
|
message: 'Invitation code not found or already used.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.meta.emailRequiredForSignup) {
|
if (this.meta.emailRequiredForSignup) {
|
||||||
if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) {
|
if (await this.usersRepository.exists({ where: { usernameLower: username.toLowerCase(), host: IsNull() } })) {
|
||||||
throw new FastifyReplyError(400, 'DUPLICATED_USERNAME');
|
return error(400, {
|
||||||
|
id: '9c20a0c3-c9e7-418f-8058-767f4e345bd4',
|
||||||
|
code: 'DUPLICATED_USERNAME',
|
||||||
|
message: 'Username already exists.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check deleted username duplication
|
// Check deleted username duplication
|
||||||
if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) {
|
if (await this.usedUsernamesRepository.exists({ where: { username: username.toLowerCase() } })) {
|
||||||
throw new FastifyReplyError(400, 'USED_USERNAME');
|
return error(400, {
|
||||||
|
id: '90e84f35-599a-468c-b420-98139fe9f988',
|
||||||
|
code: 'USED_USERNAME',
|
||||||
|
message: 'Username was previously used by another user.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPreserved = this.meta.preservedUsernames.map(x => x.toLowerCase()).includes(username.toLowerCase());
|
const isPreserved = this.meta.preservedUsernames.map(x => x.toLowerCase()).includes(username.toLowerCase());
|
||||||
if (isPreserved) {
|
if (isPreserved) {
|
||||||
throw new FastifyReplyError(400, 'DENIED_USERNAME');
|
return error(400, {
|
||||||
|
id: 'e26cbcc3-7a0c-4cf4-988f-533f56ca72bf',
|
||||||
|
code: 'DENIED_USERNAME',
|
||||||
|
message: 'This username is not allowed.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const code = secureRndstr(16, { chars: L_CHARS });
|
const code = secureRndstr(16, { chars: L_CHARS });
|
||||||
|
@ -236,6 +270,41 @@ export class SignupApiService {
|
||||||
token: secret,
|
token: secret,
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (err instanceof IdentifiableError) {
|
||||||
|
switch (err.id) {
|
||||||
|
case 'be85f7f4-1dd3-4107-bce4-07cdb0cbb0c3':
|
||||||
|
return error(400, {
|
||||||
|
id: 'f6bff66c-a3f9-48b8-b56c-3c3ffc49bfdd',
|
||||||
|
code: 'INVALID_USERNAME',
|
||||||
|
message: 'Username is invalid.',
|
||||||
|
});
|
||||||
|
case 'd5f4959c-a881-41e8-b755-718fbf161258':
|
||||||
|
return error(400, {
|
||||||
|
id: '6dffa54e-9f5f-4c07-9662-e5c75ab63ee5',
|
||||||
|
code: 'INVALID_PASSWORD',
|
||||||
|
message: 'Password is invalid.',
|
||||||
|
});
|
||||||
|
case 'd412327a-1bd7-4b70-a982-7eec000db8fc':
|
||||||
|
return error(400, {
|
||||||
|
id: '9c20a0c3-c9e7-418f-8058-767f4e345bd4',
|
||||||
|
code: 'DUPLICATED_USERNAME',
|
||||||
|
message: 'Username already exists.',
|
||||||
|
});
|
||||||
|
case 'dd5f52be-2c95-4c39-ba45-dc2d74b3dd81':
|
||||||
|
return error(400, {
|
||||||
|
id: '90e84f35-599a-468c-b420-98139fe9f988',
|
||||||
|
code: 'USED_USERNAME',
|
||||||
|
message: 'Username was previously used by another user.',
|
||||||
|
});
|
||||||
|
case 'adad138b-9c63-41bf-931e-6b050fd3bb8d':
|
||||||
|
return error(400, {
|
||||||
|
id: 'e26cbcc3-7a0c-4cf4-988f-533f56ca72bf',
|
||||||
|
code: 'DENIED_USERNAME',
|
||||||
|
message: 'This username is not allowed.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw new FastifyReplyError(400, typeof err === 'string' ? err : (err as Error).toString());
|
throw new FastifyReplyError(400, typeof err === 'string' ? err : (err as Error).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,11 +316,20 @@ export class SignupApiService {
|
||||||
|
|
||||||
const code = body['code'];
|
const code = body['code'];
|
||||||
|
|
||||||
|
function error(status: number, error: { id: string, [x: string]: string }) {
|
||||||
|
reply.code(status);
|
||||||
|
return { error };
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const pendingUser = await this.userPendingsRepository.findOneByOrFail({ code });
|
const pendingUser = await this.userPendingsRepository.findOneByOrFail({ code });
|
||||||
|
|
||||||
if (this.idService.parse(pendingUser.id).date.getTime() + (1000 * 60 * 30) < Date.now()) {
|
if (this.idService.parse(pendingUser.id).date.getTime() + (1000 * 60 * 30) < Date.now()) {
|
||||||
throw new FastifyReplyError(400, 'EXPIRED');
|
return error(400, {
|
||||||
|
id: 'e8b5b1ce-c7fe-456f-b06b-467cd16c060f',
|
||||||
|
code: 'EXPIRED',
|
||||||
|
message: 'This link has expired.',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { account, secret } = await this.signupService.signup({
|
const { account, secret } = await this.signupService.signup({
|
||||||
|
|
|
@ -268,6 +268,7 @@ async function onSubmit(): Promise<void> {
|
||||||
|
|
||||||
const res = await fetch(`${config.apiUrl}/signup`, {
|
const res = await fetch(`${config.apiUrl}/signup`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
redirect: 'error',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
|
@ -277,7 +278,8 @@ async function onSubmit(): Promise<void> {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res && res.ok) {
|
if (res) {
|
||||||
|
if (res.ok) {
|
||||||
if (res.status === 204 || instance.emailRequiredForSignup) {
|
if (res.status === 204 || instance.emailRequiredForSignup) {
|
||||||
os.alert({
|
os.alert({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
@ -295,6 +297,52 @@ async function onSubmit(): Promise<void> {
|
||||||
await login(resJson.token);
|
await login(resJson.token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
const resJson = (await res.json()) as {
|
||||||
|
error?: {
|
||||||
|
id: string;
|
||||||
|
code?: string;
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
let message: string | null = null;
|
||||||
|
|
||||||
|
if (resJson.error != null) {
|
||||||
|
if (resJson.error.message != null) {
|
||||||
|
message = resJson.error.message;
|
||||||
|
} else if (resJson.error.id != null) {
|
||||||
|
message = i18n.ts.somethingHappened + '\n' + resJson.error.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resJson.error.id) {
|
||||||
|
case '33b104c9-2f22-4640-b27a-40979bde4a77':
|
||||||
|
message = i18n.ts._signup._errors.emailInvalid;
|
||||||
|
break;
|
||||||
|
case '75ece55a-7869-49b1-b796-c0634224fcae':
|
||||||
|
message = i18n.ts._signup._errors.emailNotAllowed;
|
||||||
|
break;
|
||||||
|
case 'c8324ccf-7153-47a0-90a3-682eb06ba10d':
|
||||||
|
message = i18n.ts._signup._errors.invitationCodeInvalid;
|
||||||
|
break;
|
||||||
|
case '3277822c-29dd-4bc9-ad57-47af702f78b8':
|
||||||
|
message = i18n.ts._signup._errors.invitationCodeExpired;
|
||||||
|
break;
|
||||||
|
case 'f08118af-8358-441c-b992-b5b0bbd337d2':
|
||||||
|
message = i18n.ts._signup._errors.invitationCodeNotFoundOrUsed;
|
||||||
|
break;
|
||||||
|
case '9c20a0c3-c9e7-418f-8058-767f4e345bd4':
|
||||||
|
case '90e84f35-599a-468c-b420-98139fe9f988':
|
||||||
|
message = i18n.ts._signup._errors.usernameAlreadyUsed;
|
||||||
|
break;
|
||||||
|
case 'e26cbcc3-7a0c-4cf4-988f-533f56ca72bf':
|
||||||
|
message = i18n.ts._signup._errors.usernameNotAllowed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSignupApiError(message ? { title: i18n.ts.somethingHappened, text: message } : undefined);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
onSignupApiError();
|
onSignupApiError();
|
||||||
}
|
}
|
||||||
|
@ -302,17 +350,16 @@ async function onSubmit(): Promise<void> {
|
||||||
submitting.value = false;
|
submitting.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSignupApiError() {
|
function onSignupApiError(message?: { title?: string; text: string }): void {
|
||||||
submitting.value = false;
|
submitting.value = false;
|
||||||
hcaptcha.value?.reset?.();
|
hcaptcha.value?.reset?.();
|
||||||
mcaptcha.value?.reset?.();
|
mcaptcha.value?.reset?.();
|
||||||
recaptcha.value?.reset?.();
|
recaptcha.value?.reset?.();
|
||||||
turnstile.value?.reset?.();
|
turnstile.value?.reset?.();
|
||||||
testcaptcha.value?.reset?.();
|
testcaptcha.value?.reset?.();
|
||||||
|
|
||||||
os.alert({
|
os.alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
text: i18n.ts.somethingHappened,
|
...(message ?? { text: i18n.ts.somethingHappened }),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue