mirror of
https://tangled.org/tranquil.farm/tranquil-pds
synced 2026-09-10 04:06:05 +00:00
fix: improved discord & signal comms
This commit is contained in:
@@ -18,16 +18,18 @@
|
||||
let preferredChannel = $state('email')
|
||||
let availableCommsChannels = $state<string[]>(['email'])
|
||||
let telegramBotUsername = $state<string | undefined>(undefined)
|
||||
let discordBotUsername = $state<string | undefined>(undefined)
|
||||
let discordAppId = $state<string | undefined>(undefined)
|
||||
let email = $state('')
|
||||
let discordId = $state('')
|
||||
let discordUsername = $state('')
|
||||
let discordVerified = $state(false)
|
||||
let telegramUsername = $state('')
|
||||
let telegramVerified = $state(false)
|
||||
let signalNumber = $state('')
|
||||
let signalUsername = $state('')
|
||||
let signalVerified = $state(false)
|
||||
let savedDiscordId = $state('')
|
||||
let savedDiscordUsername = $state('')
|
||||
let savedTelegramUsername = $state('')
|
||||
let savedSignalNumber = $state('')
|
||||
let savedSignalUsername = $state('')
|
||||
let verifyingChannel = $state<string | null>(null)
|
||||
let verificationCode = $state('')
|
||||
let historyLoading = $state(true)
|
||||
@@ -57,17 +59,19 @@
|
||||
])
|
||||
preferredChannel = prefs.preferredChannel
|
||||
email = prefs.email
|
||||
discordId = prefs.discordId ?? ''
|
||||
discordUsername = prefs.discordUsername ?? ''
|
||||
discordVerified = prefs.discordVerified
|
||||
telegramUsername = prefs.telegramUsername ?? ''
|
||||
telegramVerified = prefs.telegramVerified
|
||||
signalNumber = prefs.signalNumber ?? ''
|
||||
signalUsername = prefs.signalUsername ?? ''
|
||||
signalVerified = prefs.signalVerified
|
||||
savedDiscordId = discordId
|
||||
savedDiscordUsername = discordUsername
|
||||
savedTelegramUsername = telegramUsername
|
||||
savedSignalNumber = signalNumber
|
||||
savedSignalUsername = signalUsername
|
||||
availableCommsChannels = serverInfo.availableCommsChannels ?? ['email']
|
||||
telegramBotUsername = serverInfo.telegramBotUsername
|
||||
discordBotUsername = serverInfo.discordBotUsername
|
||||
discordAppId = serverInfo.discordAppId
|
||||
} catch (e) {
|
||||
toast.error(e instanceof ApiError ? e.message : $_('comms.failedToLoad'))
|
||||
} finally {
|
||||
@@ -81,15 +85,15 @@
|
||||
try {
|
||||
const result = await api.updateNotificationPrefs(session.accessJwt, {
|
||||
preferredChannel,
|
||||
discordId: discordId !== savedDiscordId ? discordId : undefined,
|
||||
discordUsername: discordUsername !== savedDiscordUsername ? discordUsername : undefined,
|
||||
telegramUsername: telegramUsername !== savedTelegramUsername ? telegramUsername : undefined,
|
||||
signalNumber: signalNumber !== savedSignalNumber ? signalNumber : undefined,
|
||||
signalUsername: signalUsername !== savedSignalUsername ? signalUsername : undefined,
|
||||
})
|
||||
await refreshSession()
|
||||
toast.success($_('comms.preferencesSaved'))
|
||||
savedDiscordId = discordId
|
||||
savedDiscordUsername = discordUsername
|
||||
savedTelegramUsername = telegramUsername
|
||||
savedSignalNumber = signalNumber
|
||||
savedSignalUsername = signalUsername
|
||||
const channelToVerify = result.verificationRequired?.find(
|
||||
(ch: string) => ch === 'discord' || ch === 'telegram' || ch === 'signal'
|
||||
)
|
||||
@@ -108,9 +112,9 @@
|
||||
if (!verificationCode) return
|
||||
|
||||
const identifierMap: Record<string, string> = {
|
||||
discord: discordId,
|
||||
discord: discordUsername,
|
||||
telegram: telegramUsername,
|
||||
signal: signalNumber
|
||||
signal: signalUsername
|
||||
}
|
||||
const identifier = identifierMap[channel]
|
||||
if (!identifier) return
|
||||
@@ -190,9 +194,9 @@
|
||||
if (!isChannelAvailableOnServer(channelId)) return false
|
||||
if (channelId === 'email') return true
|
||||
const hasIdentifier: Record<string, boolean> = {
|
||||
discord: !!discordId,
|
||||
discord: !!discordUsername,
|
||||
telegram: !!telegramUsername,
|
||||
signal: !!signalNumber
|
||||
signal: !!signalUsername
|
||||
}
|
||||
return hasIdentifier[channelId] ?? false
|
||||
}
|
||||
@@ -245,8 +249,8 @@
|
||||
{#if isChannelAvailableOnServer('discord')}
|
||||
<div class="config-item">
|
||||
<div class="config-header">
|
||||
<label for="discord">{$_('register.discordId')}</label>
|
||||
{#if discordId}
|
||||
<label for="discord">{$_('register.discordUsername')}</label>
|
||||
{#if discordUsername}
|
||||
<span class="status" class:verified={discordVerified} class:unverified={!discordVerified}>
|
||||
{preferredChannel === 'discord' && discordVerified ? $_('comms.primary') : discordVerified ? $_('comms.verified') : $_('comms.notVerified')}
|
||||
</span>
|
||||
@@ -256,23 +260,22 @@
|
||||
<input
|
||||
id="discord"
|
||||
type="text"
|
||||
bind:value={discordId}
|
||||
onblur={() => checkChannelInUse('discord', discordId)}
|
||||
placeholder={$_('register.discordIdPlaceholder')}
|
||||
bind:value={discordUsername}
|
||||
onblur={() => checkChannelInUse('discord', discordUsername)}
|
||||
placeholder={$_('register.discordUsernamePlaceholder')}
|
||||
disabled={saving}
|
||||
/>
|
||||
{#if discordId && discordId === savedDiscordId && !discordVerified}
|
||||
<button type="button" class="verify-btn" onclick={() => verifyingChannel = 'discord'}>{$_('comms.verifyButton')}</button>
|
||||
{/if}
|
||||
</div>
|
||||
{#if discordInUse}
|
||||
<p class="hint warning">{$_('comms.discordInUseWarning')}</p>
|
||||
{/if}
|
||||
{#if verifyingChannel === 'discord'}
|
||||
<div class="verify-form">
|
||||
<input type="text" bind:value={verificationCode} placeholder={$_('comms.verifyCodePlaceholder')} maxlength="128" />
|
||||
<button type="button" onclick={() => handleVerify('discord')}>{$_('comms.submit')}</button>
|
||||
<button type="button" class="cancel" onclick={() => { verifyingChannel = null; verificationCode = '' }}>{$_('common.cancel')}</button>
|
||||
{#if discordUsername && discordUsername === savedDiscordUsername && !discordVerified && discordBotUsername}
|
||||
{@const encodedHandle = session.handle.replaceAll('.', '_')}
|
||||
<div class="discord-verify-prompt">
|
||||
{#if discordAppId}
|
||||
<a href="https://discord.com/users/{discordAppId}" target="_blank" rel="noopener">{$_('comms.discordOpenLink')}</a>
|
||||
{/if}
|
||||
<span class="manual-hint">{$_('comms.discordStartBot', { values: { botUsername: discordBotUsername, handle: session.handle } })}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -314,8 +317,8 @@
|
||||
{#if isChannelAvailableOnServer('signal')}
|
||||
<div class="config-item">
|
||||
<div class="config-header">
|
||||
<label for="signal">{$_('register.signalNumber')}</label>
|
||||
{#if signalNumber}
|
||||
<label for="signal">{$_('register.signalUsername')}</label>
|
||||
{#if signalUsername}
|
||||
<span class="status" class:verified={signalVerified} class:unverified={!signalVerified}>
|
||||
{preferredChannel === 'signal' && signalVerified ? $_('comms.primary') : signalVerified ? $_('comms.verified') : $_('comms.notVerified')}
|
||||
</span>
|
||||
@@ -324,13 +327,13 @@
|
||||
<div class="config-input">
|
||||
<input
|
||||
id="signal"
|
||||
type="tel"
|
||||
bind:value={signalNumber}
|
||||
onblur={() => checkChannelInUse('signal', signalNumber)}
|
||||
placeholder={$_('register.signalNumberPlaceholder')}
|
||||
type="text"
|
||||
bind:value={signalUsername}
|
||||
onblur={() => checkChannelInUse('signal', signalUsername)}
|
||||
placeholder={$_('register.signalUsernamePlaceholder')}
|
||||
disabled={saving}
|
||||
/>
|
||||
{#if signalNumber && signalNumber === savedSignalNumber && !signalVerified}
|
||||
{#if signalUsername && signalUsername === savedSignalUsername && !signalVerified}
|
||||
<button type="button" class="verify-btn" onclick={() => verifyingChannel = 'signal'}>{$_('comms.verifyButton')}</button>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -533,6 +536,18 @@
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.discord-verify-prompt {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
background: var(--accent-bg, var(--bg-card));
|
||||
border: 1px solid var(--accent, var(--border-color));
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--text-sm);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.manual-hint {
|
||||
font-size: var(--text-xs);
|
||||
color: var(--text-secondary);
|
||||
|
||||
@@ -404,9 +404,9 @@ export const api = {
|
||||
did: params.did,
|
||||
signingKey: params.signingKey,
|
||||
verificationChannel: params.verificationChannel,
|
||||
discordId: params.discordId,
|
||||
discordUsername: params.discordUsername,
|
||||
telegramUsername: params.telegramUsername,
|
||||
signalNumber: params.signalNumber,
|
||||
signalUsername: params.signalUsername,
|
||||
}),
|
||||
});
|
||||
const data = await response.json();
|
||||
@@ -656,9 +656,9 @@ export const api = {
|
||||
|
||||
updateNotificationPrefs(token: AccessToken, prefs: {
|
||||
preferredChannel?: string;
|
||||
discordId?: string;
|
||||
discordUsername?: string;
|
||||
telegramUsername?: string;
|
||||
signalNumber?: string;
|
||||
signalUsername?: string;
|
||||
}): Promise<UpdateNotificationPrefsResponse> {
|
||||
return xrpc("_account.updateNotificationPrefs", {
|
||||
method: "POST",
|
||||
@@ -1133,9 +1133,9 @@ export const api = {
|
||||
did?: Did;
|
||||
signingKey?: string;
|
||||
verificationChannel?: VerificationChannel;
|
||||
discordId?: string;
|
||||
discordUsername?: string;
|
||||
telegramUsername?: string;
|
||||
signalNumber?: string;
|
||||
signalUsername?: string;
|
||||
}, byodToken?: string): Promise<PasskeyAccountCreateResponse> {
|
||||
const url = `${API_BASE}/_account.createPasskeyAccount`;
|
||||
const headers: Record<string, string> = {
|
||||
@@ -1854,9 +1854,9 @@ export const typedApi = {
|
||||
token: AccessToken,
|
||||
prefs: {
|
||||
preferredChannel?: string;
|
||||
discordId?: string;
|
||||
discordUsername?: string;
|
||||
telegramUsername?: string;
|
||||
signalNumber?: string;
|
||||
signalUsername?: string;
|
||||
},
|
||||
): Promise<Result<UpdateNotificationPrefsResponse, ApiError>> {
|
||||
return xrpcResult("_account.updateNotificationPrefs", {
|
||||
|
||||
@@ -14,25 +14,31 @@
|
||||
let resending = $state(false)
|
||||
let resendMessage = $state<string | null>(null)
|
||||
let telegramBotUsername = $state<string | undefined>(undefined)
|
||||
let discordBotUsername = $state<string | undefined>(undefined)
|
||||
let discordAppId = $state<string | undefined>(undefined)
|
||||
|
||||
let pollingInterval: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
const isTelegram = $derived(flow.info.verificationChannel === 'telegram')
|
||||
const isDiscord = $derived(flow.info.verificationChannel === 'discord')
|
||||
const isBotVerified = $derived(isTelegram || isDiscord)
|
||||
|
||||
onMount(async () => {
|
||||
if (isTelegram) {
|
||||
if (isTelegram || isDiscord) {
|
||||
try {
|
||||
const serverInfo = await api.describeServer()
|
||||
telegramBotUsername = serverInfo.telegramBotUsername
|
||||
discordBotUsername = serverInfo.discordBotUsername
|
||||
discordAppId = serverInfo.discordAppId
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
if (flow.state.step === 'verify' && flow.account && (isTelegram || !verificationCode.trim())) {
|
||||
if (flow.state.step === 'verify' && flow.account && (isBotVerified || !verificationCode.trim())) {
|
||||
pollingInterval = setInterval(async () => {
|
||||
if (!isTelegram && verificationCode.trim()) return
|
||||
if (!isBotVerified && verificationCode.trim()) return
|
||||
const advanced = await flow.checkAndAdvanceIfVerified()
|
||||
if (advanced && pollingInterval) {
|
||||
clearInterval(pollingInterval)
|
||||
@@ -105,6 +111,13 @@
|
||||
or send <code>/start {handle}</code> to <code>@{telegramBotUsername}</code> manually.
|
||||
</p>
|
||||
<p class="info-text waiting">Waiting for verification...</p>
|
||||
{:else if isDiscord && discordAppId}
|
||||
{@const handle = flow.account?.handle ?? `${flow.info.handle.trim()}.${flow.state.pdsHostname}`}
|
||||
<p class="info-text">
|
||||
<a href="https://discord.com/users/{discordAppId}" target="_blank" rel="noopener">Open Discord to verify</a>,
|
||||
or send <code>/start {handle}</code> to <strong>{discordBotUsername ?? 'the bot'}</strong> manually.
|
||||
</p>
|
||||
<p class="info-text waiting">Waiting for verification...</p>
|
||||
{:else}
|
||||
<p class="info-text">
|
||||
We've sent a verification code to your {channelLabel(flow.info.verificationChannel)}.
|
||||
|
||||
@@ -56,9 +56,9 @@ export function createRegistrationFlow(
|
||||
didType: "plc",
|
||||
externalDid: "",
|
||||
verificationChannel: "email",
|
||||
discordId: "",
|
||||
discordUsername: "",
|
||||
telegramUsername: "",
|
||||
signalNumber: "",
|
||||
signalUsername: "",
|
||||
},
|
||||
externalDidWeb: {
|
||||
keyMode: "reserved",
|
||||
@@ -252,9 +252,9 @@ export function createRegistrationFlow(
|
||||
? state.externalDidWeb.reservedSigningKey
|
||||
: undefined,
|
||||
verificationChannel: state.info.verificationChannel,
|
||||
discordId: state.info.discordId?.trim() || undefined,
|
||||
discordUsername: state.info.discordUsername?.trim() || undefined,
|
||||
telegramUsername: state.info.telegramUsername?.trim() || undefined,
|
||||
signalNumber: state.info.signalNumber?.trim() || undefined,
|
||||
signalUsername: state.info.signalUsername?.trim() || undefined,
|
||||
}, byodToken);
|
||||
|
||||
state.account = {
|
||||
@@ -305,9 +305,9 @@ export function createRegistrationFlow(
|
||||
? state.externalDidWeb.reservedSigningKey
|
||||
: undefined,
|
||||
verificationChannel: state.info.verificationChannel,
|
||||
discordId: state.info.discordId?.trim() || undefined,
|
||||
discordUsername: state.info.discordUsername?.trim() || undefined,
|
||||
telegramUsername: state.info.telegramUsername?.trim() || undefined,
|
||||
signalNumber: state.info.signalNumber?.trim() || undefined,
|
||||
signalUsername: state.info.signalUsername?.trim() || undefined,
|
||||
}, byodToken);
|
||||
|
||||
state.account = {
|
||||
|
||||
@@ -28,9 +28,9 @@ export interface RegistrationInfo {
|
||||
didType: DidType;
|
||||
externalDid?: string;
|
||||
verificationChannel: VerificationChannel;
|
||||
discordId?: string;
|
||||
discordUsername?: string;
|
||||
telegramUsername?: string;
|
||||
signalNumber?: string;
|
||||
signalUsername?: string;
|
||||
}
|
||||
|
||||
export interface ExternalDidWebState {
|
||||
|
||||
@@ -185,9 +185,9 @@ export interface CreateAccountParams {
|
||||
did?: string;
|
||||
signingKey?: string;
|
||||
verificationChannel?: VerificationChannel;
|
||||
discordId?: string;
|
||||
discordUsername?: string;
|
||||
telegramUsername?: string;
|
||||
signalNumber?: string;
|
||||
signalUsername?: string;
|
||||
}
|
||||
|
||||
export interface CreateAccountResult {
|
||||
@@ -254,11 +254,11 @@ export interface ListReposResponse {
|
||||
export interface NotificationPrefs {
|
||||
preferredChannel: VerificationChannel;
|
||||
email: EmailAddress;
|
||||
discordId: string | null;
|
||||
discordUsername: string | null;
|
||||
discordVerified: boolean;
|
||||
telegramUsername: string | null;
|
||||
telegramVerified: boolean;
|
||||
signalNumber: string | null;
|
||||
signalUsername: string | null;
|
||||
signalVerified: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,11 +173,11 @@ export const reauthResponseSchema = z.object({
|
||||
export const notificationPrefsSchema = z.object({
|
||||
preferredChannel: verificationChannel,
|
||||
email: email,
|
||||
discordId: z.string().nullable(),
|
||||
discordUsername: z.string().nullable(),
|
||||
discordVerified: z.boolean(),
|
||||
telegramUsername: z.string().nullable(),
|
||||
telegramVerified: z.boolean(),
|
||||
signalNumber: z.string().nullable(),
|
||||
signalUsername: z.string().nullable(),
|
||||
signalVerified: z.boolean(),
|
||||
});
|
||||
|
||||
|
||||
@@ -84,19 +84,17 @@
|
||||
"emailAddress": "Email Address",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"discord": "Discord",
|
||||
"discordId": "Discord User ID",
|
||||
"discordIdPlaceholder": "123456789012345678",
|
||||
"discordIdHint": "Enable Developer Mode to find your ID",
|
||||
"discordInUseWarning": "Discord ID in use by another account",
|
||||
"discordUsername": "Discord Username",
|
||||
"discordUsernamePlaceholder": "yourusername",
|
||||
"discordInUseWarning": "Discord username in use by another account",
|
||||
"telegram": "Telegram",
|
||||
"telegramUsername": "Telegram Username",
|
||||
"telegramUsernamePlaceholder": "@yourusername",
|
||||
"telegramInUseWarning": "Telegram username in use by another account",
|
||||
"signal": "Signal",
|
||||
"signalNumber": "Signal Phone Number",
|
||||
"signalNumberPlaceholder": "+1234567890",
|
||||
"signalNumberHint": "Include country code",
|
||||
"signalInUseWarning": "Signal number in use by another account",
|
||||
"signalUsername": "Signal Username",
|
||||
"signalUsernamePlaceholder": "username.01",
|
||||
"signalInUseWarning": "Signal username in use by another account",
|
||||
"notConfigured": "not configured",
|
||||
"inviteCode": "Invite Code",
|
||||
"inviteCodePlaceholder": "Enter your invite code",
|
||||
@@ -118,9 +116,9 @@
|
||||
"externalDidRequired": "External did:web is required",
|
||||
"externalDidFormat": "External DID must start with did:web:",
|
||||
"emailRequired": "Email is required for email verification",
|
||||
"discordIdRequired": "Discord ID is required for Discord verification",
|
||||
"discordUsernameRequired": "Discord username is required for Discord verification",
|
||||
"telegramRequired": "Telegram username is required for Telegram verification",
|
||||
"signalRequired": "Phone number is required for Signal verification"
|
||||
"signalRequired": "Signal username is required for Signal verification"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -437,11 +435,13 @@
|
||||
"verifiedSuccess": "{channel} verified successfully",
|
||||
"messageHistory": "Message History",
|
||||
"noMessages": "No messages found.",
|
||||
"discordInUseWarning": "This Discord ID is already associated with another account.",
|
||||
"discordInUseWarning": "This Discord username is already associated with another account.",
|
||||
"telegramInUseWarning": "This Telegram username is already associated with another account.",
|
||||
"signalInUseWarning": "This Signal number is already associated with another account.",
|
||||
"signalInUseWarning": "This Signal username is already associated with another account.",
|
||||
"telegramStartBot": "Or send /start {handle} to @{botUsername} manually",
|
||||
"telegramOpenLink": "Open Telegram to verify"
|
||||
"telegramOpenLink": "Open Telegram to verify",
|
||||
"discordStartBot": "DM @{botUsername} on Discord and send /start {handle}",
|
||||
"discordOpenLink": "Open Discord to verify"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "Collections",
|
||||
@@ -779,9 +779,9 @@
|
||||
"externalDidRequired": "External did:web is required",
|
||||
"externalDidFormat": "External DID must start with did:web:",
|
||||
"emailRequired": "Email is required for email verification",
|
||||
"discordRequired": "Discord ID is required for Discord verification",
|
||||
"discordRequired": "Discord username is required for Discord verification",
|
||||
"telegramRequired": "Telegram username is required for Telegram verification",
|
||||
"signalRequired": "Phone number required",
|
||||
"signalRequired": "Signal username required",
|
||||
"passkeysNotSupported": "Passkeys not supported in this browser",
|
||||
"passkeyCancelled": "Cancelled",
|
||||
"passkeyFailed": "Passkey registration failed"
|
||||
|
||||
@@ -84,19 +84,17 @@
|
||||
"emailAddress": "Sähköpostiosoite",
|
||||
"emailPlaceholder": "sinä@esimerkki.fi",
|
||||
"discord": "Discord",
|
||||
"discordId": "Discord-käyttäjätunnus",
|
||||
"discordIdPlaceholder": "Discord-käyttäjätunnuksesi",
|
||||
"discordIdHint": "Numeerinen Discord-käyttäjätunnuksesi (ota Kehittäjätila käyttöön löytääksesi sen)",
|
||||
"discordInUseWarning": "Tämä Discord-tunnus on jo yhdistetty toiseen tiliin.",
|
||||
"discordUsername": "Discord-käyttäjänimi",
|
||||
"discordUsernamePlaceholder": "käyttäjänimesi",
|
||||
"discordInUseWarning": "Tämä Discord-käyttäjänimi on jo yhdistetty toiseen tiliin.",
|
||||
"telegram": "Telegram",
|
||||
"telegramUsername": "Telegram-käyttäjänimi",
|
||||
"telegramUsernamePlaceholder": "@käyttäjänimesi",
|
||||
"telegramInUseWarning": "Tämä Telegram-käyttäjänimi on jo yhdistetty toiseen tiliin.",
|
||||
"signal": "Signal",
|
||||
"signalNumber": "Signal-puhelinnumero",
|
||||
"signalNumberPlaceholder": "+358401234567",
|
||||
"signalNumberHint": "Sisällytä maakoodi (esim. +358 Suomelle)",
|
||||
"signalInUseWarning": "Tämä Signal-numero on jo yhdistetty toiseen tiliin.",
|
||||
"signalUsername": "Signal-käyttäjänimi",
|
||||
"signalUsernamePlaceholder": "käyttäjänimi.01",
|
||||
"signalInUseWarning": "Tämä Signal-käyttäjänimi on jo yhdistetty toiseen tiliin.",
|
||||
"notConfigured": "ei määritetty",
|
||||
"inviteCode": "Kutsukoodi",
|
||||
"inviteCodePlaceholder": "Syötä kutsukoodisi",
|
||||
@@ -118,9 +116,9 @@
|
||||
"externalDidRequired": "Ulkoinen did:web vaaditaan",
|
||||
"externalDidFormat": "Ulkoisen DID:n on alettava did:web:",
|
||||
"emailRequired": "Sähköposti vaaditaan sähköpostivahvistukseen",
|
||||
"discordIdRequired": "Discord-tunnus vaaditaan Discord-vahvistukseen",
|
||||
"discordUsernameRequired": "Discord-käyttäjänimi vaaditaan Discord-vahvistukseen",
|
||||
"telegramRequired": "Telegram-käyttäjänimi vaaditaan Telegram-vahvistukseen",
|
||||
"signalRequired": "Puhelinnumero vaaditaan Signal-vahvistukseen"
|
||||
"signalRequired": "Signal-käyttäjänimi vaaditaan Signal-vahvistukseen"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -433,11 +431,13 @@
|
||||
"verifiedSuccess": "{channel} vahvistettu",
|
||||
"messageHistory": "Viestihistoria",
|
||||
"noMessages": "Viestejä ei löytynyt.",
|
||||
"discordInUseWarning": "Tämä Discord-tunnus on jo yhdistetty toiseen tiliin.",
|
||||
"discordInUseWarning": "Tämä Discord-käyttäjänimi on jo yhdistetty toiseen tiliin.",
|
||||
"telegramInUseWarning": "Tämä Telegram-käyttäjänimi on jo yhdistetty toiseen tiliin.",
|
||||
"signalInUseWarning": "Tämä Signal-numero on jo yhdistetty toiseen tiliin.",
|
||||
"signalInUseWarning": "Tämä Signal-käyttäjänimi on jo yhdistetty toiseen tiliin.",
|
||||
"telegramStartBot": "Tai lähetä /start {handle} käyttäjälle @{botUsername} manuaalisesti",
|
||||
"telegramOpenLink": "Avaa Telegram vahvistaaksesi",
|
||||
"discordStartBot": "Lähetä @{botUsername}-botille viesti /start {handle} Discordissa",
|
||||
"discordOpenLink": "Avaa Discord vahvistaaksesi",
|
||||
"failedToLoad": "Asetusten lataus epäonnistui",
|
||||
"failedToSave": "Asetusten tallennus epäonnistui",
|
||||
"failedToVerify": "Vahvistus epäonnistui",
|
||||
@@ -751,13 +751,13 @@
|
||||
"passkeysNotSupported": "Pääsyavaimia ei tueta tässä selaimessa. Luo salasanapohjainen tili tai käytä selainta, joka tukee pääsyavaimia.",
|
||||
"passkeyCancelled": "Pääsyavaimen luominen peruutettu",
|
||||
"passkeyFailed": "Pääsyavaimen rekisteröinti epäonnistui",
|
||||
"signalRequired": "Puhelinnumero vaaditaan Signal-vahvistukseen",
|
||||
"signalRequired": "Signal-käyttäjänimi vaaditaan Signal-vahvistukseen",
|
||||
"inviteRequired": "Kutsukoodi vaaditaan",
|
||||
"externalDidRequired": "Ulkoinen did:web vaaditaan",
|
||||
"emailRequired": "Sähköposti vaaditaan sähköpostivahvistukseen",
|
||||
"telegramRequired": "Telegram-käyttäjänimi vaaditaan Telegram-vahvistukseen",
|
||||
"externalDidFormat": "Ulkoisen DID:n on alettava did:web:",
|
||||
"discordRequired": "Discord-tunnus vaaditaan Discord-vahvistukseen"
|
||||
"discordRequired": "Discord-käyttäjänimi vaaditaan Discord-vahvistukseen"
|
||||
},
|
||||
"identityType": "Identiteettityyppi",
|
||||
"identityTypeHint": "Valitse, miten hajautettua identiteettiäsi hallitaan.",
|
||||
|
||||
@@ -84,19 +84,17 @@
|
||||
"emailAddress": "メールアドレス",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"discord": "Discord",
|
||||
"discordId": "Discord ユーザー ID",
|
||||
"discordIdPlaceholder": "Discord ユーザー ID",
|
||||
"discordIdHint": "数値の Discord ユーザー ID(開発者モードを有効にして確認)",
|
||||
"discordInUseWarning": "この Discord ID は既に別のアカウントに関連付けられています。",
|
||||
"discordUsername": "Discord ユーザー名",
|
||||
"discordUsernamePlaceholder": "yourusername",
|
||||
"discordInUseWarning": "この Discord ユーザー名は既に別のアカウントに関連付けられています。",
|
||||
"telegram": "Telegram",
|
||||
"telegramUsername": "Telegram ユーザー名",
|
||||
"telegramUsernamePlaceholder": "@yourusername",
|
||||
"telegramInUseWarning": "この Telegram ユーザー名は既に別のアカウントに関連付けられています。",
|
||||
"signal": "Signal",
|
||||
"signalNumber": "Signal 電話番号",
|
||||
"signalNumberPlaceholder": "+81XXXXXXXXXX",
|
||||
"signalNumberHint": "国番号を含めてください(例: 日本は +81)",
|
||||
"signalInUseWarning": "この Signal 番号は既に別のアカウントに関連付けられています。",
|
||||
"signalUsername": "Signal ユーザー名",
|
||||
"signalUsernamePlaceholder": "username.01",
|
||||
"signalInUseWarning": "この Signal ユーザー名は既に別のアカウントに使用されています。",
|
||||
"notConfigured": "未設定",
|
||||
"inviteCode": "招待コード",
|
||||
"inviteCodePlaceholder": "招待コードを入力",
|
||||
@@ -118,9 +116,9 @@
|
||||
"externalDidRequired": "外部 did:web は必須です",
|
||||
"externalDidFormat": "外部 DID は did:web: で始まる必要があります",
|
||||
"emailRequired": "メール認証にはメールアドレスが必要です",
|
||||
"discordIdRequired": "Discord 認証には Discord ID が必要です",
|
||||
"discordUsernameRequired": "Discord 認証には Discord ユーザー名が必要です",
|
||||
"telegramRequired": "Telegram 認証には Telegram ユーザー名が必要です",
|
||||
"signalRequired": "Signal 認証には電話番号が必要です"
|
||||
"signalRequired": "Signal 認証にはユーザー名が必要です"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -433,11 +431,13 @@
|
||||
"verifiedSuccess": "{channel} を確認しました",
|
||||
"messageHistory": "メッセージ履歴",
|
||||
"noMessages": "メッセージが見つかりません。",
|
||||
"discordInUseWarning": "この Discord ID は既に別のアカウントに関連付けられています。",
|
||||
"discordInUseWarning": "この Discord ユーザー名は既に別のアカウントに関連付けられています。",
|
||||
"telegramInUseWarning": "この Telegram ユーザー名は既に別のアカウントに関連付けられています。",
|
||||
"signalInUseWarning": "この Signal 番号は既に別のアカウントに関連付けられています。",
|
||||
"signalInUseWarning": "この Signal ユーザー名は既に別のアカウントに使用されています。",
|
||||
"telegramStartBot": "または @{botUsername} に /start {handle} を手動で送信",
|
||||
"telegramOpenLink": "Telegram で確認する",
|
||||
"discordStartBot": "Discordで @{botUsername} にDMして /start {handle} を送信",
|
||||
"discordOpenLink": "Discordで認証",
|
||||
"failedToLoad": "設定の読み込みに失敗しました",
|
||||
"failedToSave": "設定の保存に失敗しました",
|
||||
"failedToVerify": "確認に失敗しました",
|
||||
@@ -751,13 +751,13 @@
|
||||
"passkeysNotSupported": "このブラウザではパスキーがサポートされていません。パスワードベースのアカウントを作成するか、パスキーをサポートするブラウザを使用してください。",
|
||||
"passkeyCancelled": "パスキーの作成がキャンセルされました",
|
||||
"passkeyFailed": "パスキーの登録に失敗しました",
|
||||
"signalRequired": "Signal認証には電話番号が必要です",
|
||||
"signalRequired": "Signal認証にはユーザー名が必要です",
|
||||
"inviteRequired": "招待コードが必要です",
|
||||
"externalDidRequired": "外部did:webが必要です",
|
||||
"emailRequired": "メール認証にはメールアドレスが必要です",
|
||||
"telegramRequired": "Telegram認証にはTelegramユーザー名が必要です",
|
||||
"externalDidFormat": "外部DIDはdid:web:で始まる必要があります",
|
||||
"discordRequired": "Discord認証にはDiscord IDが必要です"
|
||||
"discordRequired": "Discord認証にはDiscordユーザー名が必要です"
|
||||
},
|
||||
"identityType": "アイデンティティタイプ",
|
||||
"identityTypeHint": "分散型アイデンティティの管理方法を選択してください。",
|
||||
|
||||
@@ -84,19 +84,17 @@
|
||||
"emailAddress": "이메일 주소",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"discord": "Discord",
|
||||
"discordId": "Discord 사용자 ID",
|
||||
"discordIdPlaceholder": "Discord 사용자 ID",
|
||||
"discordIdHint": "숫자 Discord 사용자 ID (개발자 모드를 활성화하여 찾기)",
|
||||
"discordInUseWarning": "이 Discord ID는 이미 다른 계정과 연결되어 있습니다.",
|
||||
"discordUsername": "Discord 사용자명",
|
||||
"discordUsernamePlaceholder": "yourusername",
|
||||
"discordInUseWarning": "이 Discord 사용자명은 이미 다른 계정과 연결되어 있습니다.",
|
||||
"telegram": "Telegram",
|
||||
"telegramUsername": "Telegram 사용자 이름",
|
||||
"telegramUsernamePlaceholder": "@yourusername",
|
||||
"telegramInUseWarning": "이 Telegram 사용자 이름은 이미 다른 계정과 연결되어 있습니다.",
|
||||
"signal": "Signal",
|
||||
"signalNumber": "Signal 전화번호",
|
||||
"signalNumberPlaceholder": "+821012345678",
|
||||
"signalNumberHint": "국가 코드 포함 (예: 한국 +82)",
|
||||
"signalInUseWarning": "이 Signal 번호는 이미 다른 계정과 연결되어 있습니다.",
|
||||
"signalUsername": "Signal 사용자명",
|
||||
"signalUsernamePlaceholder": "username.01",
|
||||
"signalInUseWarning": "이 Signal 사용자명은 이미 다른 계정에서 사용 중입니다.",
|
||||
"notConfigured": "구성되지 않음",
|
||||
"inviteCode": "초대 코드",
|
||||
"inviteCodePlaceholder": "초대 코드 입력",
|
||||
@@ -118,9 +116,9 @@
|
||||
"externalDidRequired": "외부 did:web은 필수입니다",
|
||||
"externalDidFormat": "외부 DID는 did:web:으로 시작해야 합니다",
|
||||
"emailRequired": "이메일 인증에는 이메일이 필요합니다",
|
||||
"discordIdRequired": "Discord 인증에는 Discord ID가 필요합니다",
|
||||
"discordUsernameRequired": "Discord 인증에는 Discord 사용자명이 필요합니다",
|
||||
"telegramRequired": "Telegram 인증에는 Telegram 사용자 이름이 필요합니다",
|
||||
"signalRequired": "Signal 인증에는 전화번호가 필요합니다"
|
||||
"signalRequired": "Signal 인증에는 사용자명이 필요합니다"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -433,11 +431,13 @@
|
||||
"verifiedSuccess": "{channel} 인증 완료",
|
||||
"messageHistory": "메시지 기록",
|
||||
"noMessages": "메시지가 없습니다.",
|
||||
"discordInUseWarning": "이 Discord ID는 이미 다른 계정과 연결되어 있습니다.",
|
||||
"discordInUseWarning": "이 Discord 사용자명은 이미 다른 계정과 연결되어 있습니다.",
|
||||
"telegramInUseWarning": "이 Telegram 사용자 이름은 이미 다른 계정과 연결되어 있습니다.",
|
||||
"signalInUseWarning": "이 Signal 번호는 이미 다른 계정과 연결되어 있습니다.",
|
||||
"signalInUseWarning": "이 Signal 사용자명은 이미 다른 계정에서 사용 중입니다.",
|
||||
"telegramStartBot": "또는 @{botUsername}에게 /start {handle}을 직접 보내세요",
|
||||
"telegramOpenLink": "Telegram에서 인증하기",
|
||||
"discordStartBot": "Discord에서 @{botUsername}에게 DM으로 /start {handle} 보내기",
|
||||
"discordOpenLink": "Discord에서 인증",
|
||||
"failedToLoad": "설정 로딩 실패",
|
||||
"failedToSave": "설정 저장 실패",
|
||||
"failedToVerify": "인증 실패",
|
||||
@@ -751,13 +751,13 @@
|
||||
"passkeysNotSupported": "이 브라우저에서 패스키가 지원되지 않습니다. 비밀번호 기반 계정을 만들거나 패스키를 지원하는 브라우저를 사용하세요.",
|
||||
"passkeyCancelled": "패스키 생성이 취소되었습니다",
|
||||
"passkeyFailed": "패스키 등록에 실패했습니다",
|
||||
"signalRequired": "Signal 인증에는 전화번호가 필요합니다",
|
||||
"signalRequired": "Signal 인증에는 사용자명이 필요합니다",
|
||||
"inviteRequired": "초대 코드가 필요합니다",
|
||||
"externalDidRequired": "외부 did:web이 필요합니다",
|
||||
"emailRequired": "이메일 인증에는 이메일이 필요합니다",
|
||||
"telegramRequired": "Telegram 인증에는 Telegram 사용자 이름이 필요합니다",
|
||||
"externalDidFormat": "외부 DID는 did:web:으로 시작해야 합니다",
|
||||
"discordRequired": "Discord 인증에는 Discord ID가 필요합니다"
|
||||
"discordRequired": "Discord 인증에는 Discord 사용자명이 필요합니다"
|
||||
},
|
||||
"identityType": "아이덴티티 유형",
|
||||
"identityTypeHint": "분산 아이덴티티 관리 방법을 선택하세요.",
|
||||
|
||||
@@ -84,19 +84,17 @@
|
||||
"emailAddress": "E-postadress",
|
||||
"emailPlaceholder": "du@exempel.se",
|
||||
"discord": "Discord",
|
||||
"discordId": "Discord användar-ID",
|
||||
"discordIdPlaceholder": "Ditt Discord användar-ID",
|
||||
"discordIdHint": "Ditt numeriska Discord användar-ID (aktivera Utvecklarläge för att hitta det)",
|
||||
"discordInUseWarning": "Detta Discord-ID är redan kopplat till ett annat konto.",
|
||||
"discordUsername": "Discord-användarnamn",
|
||||
"discordUsernamePlaceholder": "dittanvändarnamn",
|
||||
"discordInUseWarning": "Detta Discord-användarnamn är redan kopplat till ett annat konto.",
|
||||
"telegram": "Telegram",
|
||||
"telegramUsername": "Telegram-användarnamn",
|
||||
"telegramUsernamePlaceholder": "@dittanvändarnamn",
|
||||
"telegramInUseWarning": "Detta Telegram-användarnamn är redan kopplat till ett annat konto.",
|
||||
"signal": "Signal",
|
||||
"signalNumber": "Signal-telefonnummer",
|
||||
"signalNumberPlaceholder": "+46701234567",
|
||||
"signalNumberHint": "Inkludera landskod (t.ex. +46 för Sverige)",
|
||||
"signalInUseWarning": "Detta Signal-nummer är redan kopplat till ett annat konto.",
|
||||
"signalUsername": "Signal-användarnamn",
|
||||
"signalUsernamePlaceholder": "användarnamn.01",
|
||||
"signalInUseWarning": "Detta Signal-användarnamn är redan kopplat till ett annat konto.",
|
||||
"notConfigured": "ej konfigurerad",
|
||||
"inviteCode": "Inbjudningskod",
|
||||
"inviteCodePlaceholder": "Ange din inbjudningskod",
|
||||
@@ -118,9 +116,9 @@
|
||||
"externalDidRequired": "Extern did:web krävs",
|
||||
"externalDidFormat": "Extern DID måste börja med did:web:",
|
||||
"emailRequired": "E-post krävs för e-postverifiering",
|
||||
"discordIdRequired": "Discord-ID krävs för Discord-verifiering",
|
||||
"discordUsernameRequired": "Discord-användarnamn krävs för Discord-verifiering",
|
||||
"telegramRequired": "Telegram-användarnamn krävs för Telegram-verifiering",
|
||||
"signalRequired": "Telefonnummer krävs för Signal-verifiering"
|
||||
"signalRequired": "Signal-användarnamn krävs för Signal-verifiering"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -433,11 +431,13 @@
|
||||
"verifiedSuccess": "{channel} verifierad",
|
||||
"messageHistory": "Meddelandehistorik",
|
||||
"noMessages": "Inga meddelanden hittades.",
|
||||
"discordInUseWarning": "Detta Discord-ID är redan kopplat till ett annat konto.",
|
||||
"discordInUseWarning": "Detta Discord-användarnamn är redan kopplat till ett annat konto.",
|
||||
"telegramInUseWarning": "Detta Telegram-användarnamn är redan kopplat till ett annat konto.",
|
||||
"signalInUseWarning": "Detta Signal-nummer är redan kopplat till ett annat konto.",
|
||||
"signalInUseWarning": "Detta Signal-användarnamn är redan kopplat till ett annat konto.",
|
||||
"telegramStartBot": "Eller skicka /start {handle} till @{botUsername} manuellt",
|
||||
"telegramOpenLink": "Öppna Telegram för att verifiera",
|
||||
"discordStartBot": "DM:a @{botUsername} på Discord och skicka /start {handle}",
|
||||
"discordOpenLink": "Öppna Discord för att verifiera",
|
||||
"failedToLoad": "Kunde inte ladda inställningar",
|
||||
"failedToSave": "Kunde inte spara inställningar",
|
||||
"failedToVerify": "Verifiering misslyckades",
|
||||
@@ -751,13 +751,13 @@
|
||||
"passkeysNotSupported": "Nycklar stöds inte i denna webbläsare. Skapa ett lösenordsbaserat konto eller använd en webbläsare som stöder nycklar.",
|
||||
"passkeyCancelled": "Nyckelskapande avbröts",
|
||||
"passkeyFailed": "Nyckelregistrering misslyckades",
|
||||
"signalRequired": "Telefonnummer krävs för Signal-verifiering",
|
||||
"signalRequired": "Signal-användarnamn krävs för Signal-verifiering",
|
||||
"inviteRequired": "Inbjudningskod krävs",
|
||||
"externalDidRequired": "Extern did:web krävs",
|
||||
"emailRequired": "E-post krävs för e-postverifiering",
|
||||
"telegramRequired": "Telegram-användarnamn krävs för Telegram-verifiering",
|
||||
"externalDidFormat": "Extern DID måste börja med did:web:",
|
||||
"discordRequired": "Discord-ID krävs för Discord-verifiering"
|
||||
"discordRequired": "Discord-användarnamn krävs för Discord-verifiering"
|
||||
},
|
||||
"identityType": "Identitetstyp",
|
||||
"identityTypeHint": "Välj hur din decentraliserade identitet ska hanteras.",
|
||||
|
||||
@@ -84,19 +84,17 @@
|
||||
"emailAddress": "电子邮件地址",
|
||||
"emailPlaceholder": "you@example.com",
|
||||
"discord": "Discord",
|
||||
"discordId": "Discord 用户 ID",
|
||||
"discordIdPlaceholder": "您的 Discord 用户 ID",
|
||||
"discordIdHint": "您的 Discord 数字用户 ID(开启开发者模式后可以复制)",
|
||||
"discordInUseWarning": "此 Discord ID 已与另一个账户关联。",
|
||||
"discordUsername": "Discord 用户名",
|
||||
"discordUsernamePlaceholder": "yourusername",
|
||||
"discordInUseWarning": "此 Discord 用户名已与另一个账户关联。",
|
||||
"telegram": "Telegram",
|
||||
"telegramUsername": "Telegram 用户名",
|
||||
"telegramUsernamePlaceholder": "@yourusername",
|
||||
"telegramInUseWarning": "此 Telegram 用户名已与另一个账户关联。",
|
||||
"signal": "Signal",
|
||||
"signalNumber": "Signal 电话号码",
|
||||
"signalNumberPlaceholder": "+1234567890",
|
||||
"signalNumberHint": "包含国家代码(例如中国为 +86)",
|
||||
"signalInUseWarning": "此 Signal 号码已与另一个账户关联。",
|
||||
"signalUsername": "Signal 用户名",
|
||||
"signalUsernamePlaceholder": "username.01",
|
||||
"signalInUseWarning": "此 Signal 用户名已被其他账户使用。",
|
||||
"notConfigured": "未配置",
|
||||
"inviteCode": "邀请码",
|
||||
"inviteCodePlaceholder": "输入您的邀请码",
|
||||
@@ -118,9 +116,9 @@
|
||||
"externalDidRequired": "请输入您的 did:web",
|
||||
"externalDidFormat": "DID 必须以 did:web: 开头",
|
||||
"emailRequired": "使用邮箱验证需要填写邮箱地址",
|
||||
"discordIdRequired": "使用 Discord 验证需要填写 Discord ID",
|
||||
"discordUsernameRequired": "使用 Discord 验证需要填写 Discord 用户名",
|
||||
"telegramRequired": "使用 Telegram 验证需要填写用户名",
|
||||
"signalRequired": "使用 Signal 验证需要填写电话号码"
|
||||
"signalRequired": "使用 Signal 验证需要填写用户名"
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
@@ -433,11 +431,13 @@
|
||||
"verifiedSuccess": "{channel} 验证成功",
|
||||
"messageHistory": "消息历史",
|
||||
"noMessages": "暂无消息记录",
|
||||
"discordInUseWarning": "此 Discord ID 已与另一个账户关联。",
|
||||
"discordInUseWarning": "此 Discord 用户名已与另一个账户关联。",
|
||||
"telegramInUseWarning": "此 Telegram 用户名已与另一个账户关联。",
|
||||
"signalInUseWarning": "此 Signal 号码已与另一个账户关联。",
|
||||
"signalInUseWarning": "此 Signal 用户名已与另一个账户关联。",
|
||||
"telegramStartBot": "或手动向 @{botUsername} 发送 /start {handle}",
|
||||
"telegramOpenLink": "打开 Telegram 验证",
|
||||
"discordStartBot": "在 Discord 上私信 @{botUsername} 并发送 /start {handle}",
|
||||
"discordOpenLink": "打开 Discord 验证",
|
||||
"failedToLoad": "加载偏好设置失败",
|
||||
"failedToSave": "保存偏好设置失败",
|
||||
"failedToVerify": "验证失败",
|
||||
@@ -774,9 +774,9 @@
|
||||
"externalDidRequired": "请输入您的 did:web",
|
||||
"externalDidFormat": "DID 必须以 did:web: 开头",
|
||||
"emailRequired": "使用邮箱验证需要填写邮箱地址",
|
||||
"discordRequired": "使用 Discord 验证需要填写 Discord ID",
|
||||
"discordRequired": "使用 Discord 验证需要填写 Discord 用户名",
|
||||
"telegramRequired": "使用 Telegram 验证需要填写用户名",
|
||||
"signalRequired": "使用 Signal 验证需要填写电话号码",
|
||||
"signalRequired": "使用 Signal 验证需要填写用户名",
|
||||
"passkeysNotSupported": "此浏览器不支持通行密钥。请使用其他浏览器或使用密码注册。",
|
||||
"passkeyCancelled": "通行密钥创建已取消",
|
||||
"passkeyFailed": "通行密钥注册失败"
|
||||
|
||||
@@ -123,13 +123,13 @@
|
||||
if (!info.email.trim()) return $_('registerPasskey.errors.emailRequired')
|
||||
break
|
||||
case 'discord':
|
||||
if (!info.discordId?.trim()) return $_('registerPasskey.errors.discordRequired')
|
||||
if (!info.discordUsername?.trim()) return $_('registerPasskey.errors.discordRequired')
|
||||
break
|
||||
case 'telegram':
|
||||
if (!info.telegramUsername?.trim()) return $_('registerPasskey.errors.telegramRequired')
|
||||
break
|
||||
case 'signal':
|
||||
if (!info.signalNumber?.trim()) return $_('registerPasskey.errors.signalRequired')
|
||||
if (!info.signalUsername?.trim()) return $_('registerPasskey.errors.signalRequired')
|
||||
break
|
||||
}
|
||||
return null
|
||||
@@ -389,16 +389,15 @@
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'discord'}
|
||||
<div class="field">
|
||||
<label for="discord-id">{$_('register.discordId')}</label>
|
||||
<label for="discord-username">{$_('register.discordUsername')}</label>
|
||||
<input
|
||||
id="discord-id"
|
||||
id="discord-username"
|
||||
type="text"
|
||||
bind:value={flow.info.discordId}
|
||||
placeholder={$_('register.discordIdPlaceholder')}
|
||||
bind:value={flow.info.discordUsername}
|
||||
placeholder={$_('register.discordUsernamePlaceholder')}
|
||||
disabled={flow.state.submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.discordIdHint')}</p>
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'telegram'}
|
||||
<div class="field">
|
||||
@@ -414,16 +413,16 @@
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'signal'}
|
||||
<div class="field">
|
||||
<label for="signal-number">{$_('register.signalNumber')}</label>
|
||||
<label for="signal-number">{$_('register.signalUsername')}</label>
|
||||
<input
|
||||
id="signal-number"
|
||||
type="tel"
|
||||
bind:value={flow.info.signalNumber}
|
||||
placeholder={$_('register.signalNumberPlaceholder')}
|
||||
bind:value={flow.info.signalUsername}
|
||||
placeholder={$_('register.signalUsernamePlaceholder')}
|
||||
disabled={flow.state.submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.signalNumberHint')}</p>
|
||||
<p class="hint">{$_('register.signalUsernameHint')}</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
let providerEmailOriginal = $state<string | null>(null)
|
||||
let inviteCode = $state('')
|
||||
let verificationChannel = $state('email')
|
||||
let discordId = $state('')
|
||||
let discordUsername = $state('')
|
||||
let telegramUsername = $state('')
|
||||
let signalNumber = $state('')
|
||||
let signalUsername = $state('')
|
||||
|
||||
let handleAvailable = $state<boolean | null>(null)
|
||||
let checkingHandle = $state(false)
|
||||
@@ -189,11 +189,11 @@
|
||||
case 'email':
|
||||
return !!email.trim()
|
||||
case 'discord':
|
||||
return !!discordId.trim()
|
||||
return !!discordUsername.trim()
|
||||
case 'telegram':
|
||||
return !!telegramUsername.trim()
|
||||
case 'signal':
|
||||
return !!signalNumber.trim()
|
||||
return !!signalUsername.trim()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -234,9 +234,9 @@
|
||||
email: email || null,
|
||||
invite_code: inviteCode || null,
|
||||
verification_channel: verificationChannel,
|
||||
discord_id: discordId || null,
|
||||
discord_username: discordUsername || null,
|
||||
telegram_username: telegramUsername || null,
|
||||
signal_number: signalNumber || null,
|
||||
signal_username: signalUsername || null,
|
||||
did_type: didType,
|
||||
did: didType === 'web-external' ? externalDid.trim() : null,
|
||||
}),
|
||||
@@ -379,16 +379,15 @@
|
||||
</div>
|
||||
{:else if verificationChannel === 'discord'}
|
||||
<div class="field">
|
||||
<label for="discord-id">{$_('register.discordId')}</label>
|
||||
<label for="discord-username">{$_('register.discordUsername')}</label>
|
||||
<input
|
||||
id="discord-id"
|
||||
id="discord-username"
|
||||
type="text"
|
||||
bind:value={discordId}
|
||||
placeholder={$_('register.discordIdPlaceholder')}
|
||||
bind:value={discordUsername}
|
||||
placeholder={$_('register.discordUsernamePlaceholder')}
|
||||
disabled={submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.discordIdHint')}</p>
|
||||
</div>
|
||||
{:else if verificationChannel === 'telegram'}
|
||||
<div class="field">
|
||||
@@ -404,16 +403,16 @@
|
||||
</div>
|
||||
{:else if verificationChannel === 'signal'}
|
||||
<div class="field">
|
||||
<label for="signal-number">{$_('register.signalNumber')}</label>
|
||||
<label for="signal-number">{$_('register.signalUsername')}</label>
|
||||
<input
|
||||
id="signal-number"
|
||||
type="tel"
|
||||
bind:value={signalNumber}
|
||||
placeholder={$_('register.signalNumberPlaceholder')}
|
||||
bind:value={signalUsername}
|
||||
placeholder={$_('register.signalUsernamePlaceholder')}
|
||||
disabled={submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.signalNumberHint')}</p>
|
||||
<p class="hint">{$_('register.signalUsernameHint')}</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -136,13 +136,13 @@
|
||||
if (!info.email.trim()) return $_('registerPasskey.errors.emailRequired')
|
||||
break
|
||||
case 'discord':
|
||||
if (!info.discordId?.trim()) return $_('registerPasskey.errors.discordRequired')
|
||||
if (!info.discordUsername?.trim()) return $_('registerPasskey.errors.discordRequired')
|
||||
break
|
||||
case 'telegram':
|
||||
if (!info.telegramUsername?.trim()) return $_('registerPasskey.errors.telegramRequired')
|
||||
break
|
||||
case 'signal':
|
||||
if (!info.signalNumber?.trim()) return $_('registerPasskey.errors.signalRequired')
|
||||
if (!info.signalUsername?.trim()) return $_('registerPasskey.errors.signalRequired')
|
||||
break
|
||||
}
|
||||
return null
|
||||
@@ -409,16 +409,15 @@
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'discord'}
|
||||
<div class="field">
|
||||
<label for="discord-id">{$_('register.discordId')}</label>
|
||||
<label for="discord-username">{$_('register.discordUsername')}</label>
|
||||
<input
|
||||
id="discord-id"
|
||||
id="discord-username"
|
||||
type="text"
|
||||
bind:value={flow.info.discordId}
|
||||
placeholder={$_('register.discordIdPlaceholder')}
|
||||
bind:value={flow.info.discordUsername}
|
||||
placeholder={$_('register.discordUsernamePlaceholder')}
|
||||
disabled={flow.state.submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.discordIdHint')}</p>
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'telegram'}
|
||||
<div class="field">
|
||||
@@ -434,16 +433,16 @@
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'signal'}
|
||||
<div class="field">
|
||||
<label for="signal-number">{$_('register.signalNumber')}</label>
|
||||
<label for="signal-number">{$_('register.signalUsername')}</label>
|
||||
<input
|
||||
id="signal-number"
|
||||
type="tel"
|
||||
bind:value={flow.info.signalNumber}
|
||||
placeholder={$_('register.signalNumberPlaceholder')}
|
||||
bind:value={flow.info.signalUsername}
|
||||
placeholder={$_('register.signalUsernamePlaceholder')}
|
||||
disabled={flow.state.submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.signalNumberHint')}</p>
|
||||
<p class="hint">{$_('register.signalUsernameHint')}</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -133,13 +133,13 @@
|
||||
if (!info.email.trim()) return $_('register.validation.emailRequired')
|
||||
break
|
||||
case 'discord':
|
||||
if (!info.discordId?.trim()) return $_('register.validation.discordIdRequired')
|
||||
if (!info.discordUsername?.trim()) return $_('register.validation.discordUsernameRequired')
|
||||
break
|
||||
case 'telegram':
|
||||
if (!info.telegramUsername?.trim()) return $_('register.validation.telegramRequired')
|
||||
break
|
||||
case 'signal':
|
||||
if (!info.signalNumber?.trim()) return $_('register.validation.signalRequired')
|
||||
if (!info.signalUsername?.trim()) return $_('register.validation.signalRequired')
|
||||
break
|
||||
}
|
||||
return null
|
||||
@@ -381,17 +381,16 @@
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'discord'}
|
||||
<div class="field">
|
||||
<label for="discord-id">{$_('register.discordId')}</label>
|
||||
<label for="discord-username">{$_('register.discordUsername')}</label>
|
||||
<input
|
||||
id="discord-id"
|
||||
id="discord-username"
|
||||
type="text"
|
||||
bind:value={flow.info.discordId}
|
||||
onblur={() => flow?.checkCommsChannelInUse('discord', flow.info.discordId ?? '')}
|
||||
placeholder={$_('register.discordIdPlaceholder')}
|
||||
bind:value={flow.info.discordUsername}
|
||||
onblur={() => flow?.checkCommsChannelInUse('discord', flow.info.discordUsername ?? '')}
|
||||
placeholder={$_('register.discordUsernamePlaceholder')}
|
||||
disabled={flow.state.submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.discordIdHint')}</p>
|
||||
{#if flow.state.discordInUse}
|
||||
<p class="hint warning">{$_('register.discordInUseWarning')}</p>
|
||||
{/if}
|
||||
@@ -414,17 +413,17 @@
|
||||
</div>
|
||||
{:else if flow.info.verificationChannel === 'signal'}
|
||||
<div class="field">
|
||||
<label for="signal-number">{$_('register.signalNumber')}</label>
|
||||
<label for="signal-number">{$_('register.signalUsername')}</label>
|
||||
<input
|
||||
id="signal-number"
|
||||
type="tel"
|
||||
bind:value={flow.info.signalNumber}
|
||||
onblur={() => flow?.checkCommsChannelInUse('signal', flow.info.signalNumber ?? '')}
|
||||
placeholder={$_('register.signalNumberPlaceholder')}
|
||||
bind:value={flow.info.signalUsername}
|
||||
onblur={() => flow?.checkCommsChannelInUse('signal', flow.info.signalUsername ?? '')}
|
||||
placeholder={$_('register.signalUsernamePlaceholder')}
|
||||
disabled={flow.state.submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.signalNumberHint')}</p>
|
||||
<p class="hint">{$_('register.signalUsernameHint')}</p>
|
||||
{#if flow.state.signalInUse}
|
||||
<p class="hint warning">{$_('register.signalInUseWarning')}</p>
|
||||
{/if}
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
let providerEmailOriginal = $state<string | null>(null)
|
||||
let inviteCode = $state('')
|
||||
let verificationChannel = $state('email')
|
||||
let discordId = $state('')
|
||||
let discordUsername = $state('')
|
||||
let telegramUsername = $state('')
|
||||
let signalNumber = $state('')
|
||||
let signalUsername = $state('')
|
||||
|
||||
let handleAvailable = $state<boolean | null>(null)
|
||||
let checkingHandle = $state(false)
|
||||
@@ -204,11 +204,11 @@
|
||||
case 'email':
|
||||
return !!email.trim()
|
||||
case 'discord':
|
||||
return !!discordId.trim()
|
||||
return !!discordUsername.trim()
|
||||
case 'telegram':
|
||||
return !!telegramUsername.trim()
|
||||
case 'signal':
|
||||
return !!signalNumber.trim()
|
||||
return !!signalUsername.trim()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
@@ -281,9 +281,9 @@
|
||||
email: email || null,
|
||||
invite_code: inviteCode || null,
|
||||
verification_channel: verificationChannel,
|
||||
discord_id: discordId || null,
|
||||
discord_username: discordUsername || null,
|
||||
telegram_username: telegramUsername || null,
|
||||
signal_number: signalNumber || null,
|
||||
signal_username: signalUsername || null,
|
||||
did_type: didType,
|
||||
did: didType === 'web-external' ? externalDid.trim() : null,
|
||||
}),
|
||||
@@ -452,16 +452,15 @@
|
||||
</div>
|
||||
{:else if verificationChannel === 'discord'}
|
||||
<div class="field">
|
||||
<label for="discord-id">{$_('register.discordId')}</label>
|
||||
<label for="discord-username">{$_('register.discordUsername')}</label>
|
||||
<input
|
||||
id="discord-id"
|
||||
id="discord-username"
|
||||
type="text"
|
||||
bind:value={discordId}
|
||||
placeholder={$_('register.discordIdPlaceholder')}
|
||||
bind:value={discordUsername}
|
||||
placeholder={$_('register.discordUsernamePlaceholder')}
|
||||
disabled={submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.discordIdHint')}</p>
|
||||
</div>
|
||||
{:else if verificationChannel === 'telegram'}
|
||||
<div class="field">
|
||||
@@ -477,16 +476,16 @@
|
||||
</div>
|
||||
{:else if verificationChannel === 'signal'}
|
||||
<div class="field">
|
||||
<label for="signal-number">{$_('register.signalNumber')}</label>
|
||||
<label for="signal-number">{$_('register.signalUsername')}</label>
|
||||
<input
|
||||
id="signal-number"
|
||||
type="tel"
|
||||
bind:value={signalNumber}
|
||||
placeholder={$_('register.signalNumberPlaceholder')}
|
||||
bind:value={signalUsername}
|
||||
placeholder={$_('register.signalUsernamePlaceholder')}
|
||||
disabled={submitting}
|
||||
required
|
||||
/>
|
||||
<p class="hint">{$_('register.signalNumberHint')}</p>
|
||||
<p class="hint">{$_('register.signalUsernameHint')}</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
let tokenFromUrl = $state(false)
|
||||
let oauthRequestUri = $state<string | null>(null)
|
||||
let telegramBotUsername = $state<string | undefined>(undefined)
|
||||
let discordBotUsername = $state<string | undefined>(undefined)
|
||||
let discordAppId = $state<string | undefined>(undefined)
|
||||
|
||||
const auth = $derived(getAuthState())
|
||||
|
||||
@@ -42,6 +44,8 @@
|
||||
|
||||
const session = $derived(getSession())
|
||||
const isTelegram = $derived(pendingVerification?.channel === 'telegram')
|
||||
const isDiscord = $derived(pendingVerification?.channel === 'discord')
|
||||
const isBotVerified = $derived(isTelegram || isDiscord)
|
||||
|
||||
function parseQueryParams(): Record<string, string> {
|
||||
return Object.fromEntries(new URLSearchParams(window.location.search))
|
||||
@@ -102,10 +106,12 @@
|
||||
}))
|
||||
}
|
||||
|
||||
if (pendingVerification?.channel === 'telegram') {
|
||||
if (pendingVerification?.channel === 'telegram' || pendingVerification?.channel === 'discord') {
|
||||
try {
|
||||
const serverInfo = await api.describeServer()
|
||||
telegramBotUsername = serverInfo.telegramBotUsername
|
||||
discordBotUsername = serverInfo.discordBotUsername
|
||||
discordAppId = serverInfo.discordAppId
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
@@ -121,10 +127,10 @@
|
||||
|
||||
let pollingVerification = false
|
||||
$effect(() => {
|
||||
if (mode === 'signup' && pendingVerification && (isTelegram || !verificationCode.trim())) {
|
||||
if (mode === 'signup' && pendingVerification && (isBotVerified || !verificationCode.trim())) {
|
||||
const currentPending = pendingVerification
|
||||
const interval = setInterval(async () => {
|
||||
if (pollingVerification || (!isTelegram && verificationCode.trim())) return
|
||||
if (pollingVerification || (!isBotVerified && verificationCode.trim())) return
|
||||
pollingVerification = true
|
||||
try {
|
||||
const result = await api.checkChannelVerified(currentPending.did, currentPending.channel)
|
||||
@@ -447,7 +453,7 @@
|
||||
|
||||
{#if isTelegram && telegramBotUsername}
|
||||
{@const encodedHandle = pendingVerification.handle.replaceAll('.', '_')}
|
||||
<div class="telegram-hint">
|
||||
<div class="bot-hint">
|
||||
<p>
|
||||
<a href="https://t.me/{telegramBotUsername}?start={encodedHandle}" target="_blank" rel="noopener">{$_('comms.telegramOpenLink')}</a>
|
||||
</p>
|
||||
@@ -456,6 +462,16 @@
|
||||
</p>
|
||||
<p class="waiting-text">{$_('verify.pleaseWait')}</p>
|
||||
</div>
|
||||
{:else if isDiscord && discordAppId}
|
||||
<div class="bot-hint">
|
||||
<p>
|
||||
<a href="https://discord.com/users/{discordAppId}" target="_blank" rel="noopener">{$_('comms.discordOpenLink')}</a>
|
||||
</p>
|
||||
<p class="manual-text">
|
||||
{$_('comms.discordStartBot', { values: { botUsername: discordBotUsername ?? 'the bot', handle: pendingVerification.handle } })}
|
||||
</p>
|
||||
<p class="waiting-text">{$_('verify.pleaseWait')}</p>
|
||||
</div>
|
||||
{:else}
|
||||
<form onsubmit={(e) => { e.preventDefault(); handleSignupVerification(e); }}>
|
||||
<div class="field">
|
||||
@@ -610,23 +626,23 @@
|
||||
padding: var(--space-4) var(--space-8);
|
||||
}
|
||||
|
||||
.telegram-hint {
|
||||
.bot-hint {
|
||||
padding: var(--space-4);
|
||||
background: var(--bg-secondary);
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
.telegram-hint p {
|
||||
.bot-hint p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.telegram-hint .manual-text {
|
||||
.bot-hint .manual-text {
|
||||
font-size: var(--text-sm);
|
||||
color: var(--text-secondary);
|
||||
margin-top: var(--space-1);
|
||||
}
|
||||
|
||||
.telegram-hint .waiting-text {
|
||||
.bot-hint .waiting-text {
|
||||
font-size: var(--text-sm);
|
||||
color: var(--text-secondary);
|
||||
margin-top: var(--space-2);
|
||||
|
||||
@@ -254,11 +254,11 @@ export const mockData = {
|
||||
notificationPrefs: (overrides?: Record<string, unknown>) => ({
|
||||
preferredChannel: "email",
|
||||
email: "test@example.com",
|
||||
discordId: null,
|
||||
discordUsername: null,
|
||||
discordVerified: false,
|
||||
telegramUsername: null,
|
||||
telegramVerified: false,
|
||||
signalNumber: null,
|
||||
signalUsername: null,
|
||||
signalVerified: false,
|
||||
...overrides,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user