@getauthui/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/authui-user-button-3yi-kvES.js +4139 -0
- package/dist/authui.cdn.js +2018 -0
- package/dist/authui.cdn.mjs +7565 -0
- package/dist/authui.d.ts +743 -0
- package/dist/authui.js +66 -0
- package/dist/react.d.ts +395 -0
- package/dist/react.js +68 -0
- package/package.json +75 -0
|
@@ -0,0 +1,4139 @@
|
|
|
1
|
+
import { state as d, property as g, customElement as S, query as X } from "lit/decorators.js";
|
|
2
|
+
import { css as A, LitElement as V, nothing as n, html as s, svg as l } from "lit";
|
|
3
|
+
import { Client as Q, Account as J, ID as z, Avatars as tt } from "appwrite";
|
|
4
|
+
const et = {
|
|
5
|
+
signIn: "Sign in",
|
|
6
|
+
signUp: "Sign up",
|
|
7
|
+
signOut: "Sign out",
|
|
8
|
+
continueAsGuest: "Continue as guest",
|
|
9
|
+
email: "Email",
|
|
10
|
+
password: "Password",
|
|
11
|
+
newPassword: "New password",
|
|
12
|
+
confirmPassword: "Confirm password",
|
|
13
|
+
name: "Name",
|
|
14
|
+
phone: "Phone number",
|
|
15
|
+
code: "Code",
|
|
16
|
+
forgotPassword: "Forgot password?",
|
|
17
|
+
noAccount: "Don't have an account?",
|
|
18
|
+
haveAccount: "Already have an account?",
|
|
19
|
+
or: "or",
|
|
20
|
+
continueWith: "Continue with {provider}",
|
|
21
|
+
continueWithEmail: "Continue with email",
|
|
22
|
+
sendEmailCode: "Email me a code",
|
|
23
|
+
continueWithPhone: "Continue with phone",
|
|
24
|
+
sendMagicLink: "Send magic link",
|
|
25
|
+
sendCode: "Send code",
|
|
26
|
+
verifyCode: "Verify code",
|
|
27
|
+
magicLinkSent: "We sent a sign-in link to {email}. Open it on this device to continue.",
|
|
28
|
+
codeSent: "We sent a code to {target}. Enter it below to continue.",
|
|
29
|
+
securityPhrase: "Security phrase",
|
|
30
|
+
securityPhraseHint: "The message we sent includes this phrase. Do not continue if it differs.",
|
|
31
|
+
back: "Back",
|
|
32
|
+
cancel: "Cancel",
|
|
33
|
+
save: "Save",
|
|
34
|
+
update: "Update",
|
|
35
|
+
remove: "Remove",
|
|
36
|
+
close: "Close",
|
|
37
|
+
resetPassword: "Reset password",
|
|
38
|
+
resetLinkSent: "If an account exists for {email}, a reset link is on its way.",
|
|
39
|
+
passwordUpdated: "Your password was updated. You can sign in now.",
|
|
40
|
+
sendResetLink: "Send reset link",
|
|
41
|
+
agreeTo: "By continuing you agree to our",
|
|
42
|
+
terms: "Terms of Service",
|
|
43
|
+
privacy: "Privacy Policy",
|
|
44
|
+
and: "and",
|
|
45
|
+
welcomeBack: "Welcome back",
|
|
46
|
+
createAccount: "Create your account",
|
|
47
|
+
signInTitle: "Sign in to {name}",
|
|
48
|
+
signUpTitle: "Sign up for {name}",
|
|
49
|
+
mfaTitle: "Two-factor authentication",
|
|
50
|
+
mfaDescription: "Confirm it is you with a second factor.",
|
|
51
|
+
mfaUseAuthenticator: "Use authenticator app",
|
|
52
|
+
mfaUseEmail: "Send code to email",
|
|
53
|
+
mfaUsePhone: "Send code by SMS",
|
|
54
|
+
mfaUseRecoveryCode: "Use a recovery code",
|
|
55
|
+
recoveryCode: "Recovery code",
|
|
56
|
+
account: "Account",
|
|
57
|
+
profile: "Profile",
|
|
58
|
+
security: "Security",
|
|
59
|
+
sessions: "Sessions",
|
|
60
|
+
connections: "Connections",
|
|
61
|
+
activity: "Activity",
|
|
62
|
+
dangerZone: "Danger zone",
|
|
63
|
+
verified: "Verified",
|
|
64
|
+
unverified: "Unverified",
|
|
65
|
+
verifyEmail: "Verify email",
|
|
66
|
+
verificationSent: "Verification email sent. Check your inbox.",
|
|
67
|
+
emailVerified: "Your email is verified.",
|
|
68
|
+
changePassword: "Change password",
|
|
69
|
+
currentPassword: "Current password",
|
|
70
|
+
twoFactor: "Two-factor authentication",
|
|
71
|
+
twoFactorDescription: "Require a second factor when signing in to this account.",
|
|
72
|
+
enable: "Enable",
|
|
73
|
+
disable: "Disable",
|
|
74
|
+
authenticatorApp: "Authenticator app",
|
|
75
|
+
authenticatorAdd: "Add authenticator",
|
|
76
|
+
authenticatorScan: "Scan this QR code with your authenticator app, then enter the 6-digit code.",
|
|
77
|
+
authenticatorManual: "Or enter this key manually",
|
|
78
|
+
authenticatorVerify: "Verify and enable",
|
|
79
|
+
recoveryCodes: "Recovery codes",
|
|
80
|
+
recoveryCodesDescription: "Use a recovery code to sign in if you lose access to your other factors.",
|
|
81
|
+
generateRecoveryCodes: "Generate recovery codes",
|
|
82
|
+
regenerateRecoveryCodes: "Regenerate",
|
|
83
|
+
recoveryCodesWarning: "Store these codes somewhere safe. Each code works once.",
|
|
84
|
+
currentSession: "This device",
|
|
85
|
+
signOutSession: "Sign out",
|
|
86
|
+
signOutAllSessions: "Sign out everywhere",
|
|
87
|
+
signOutAllSessionsDescription: "End every session, including this one.",
|
|
88
|
+
noConnections: "No connected accounts.",
|
|
89
|
+
disconnect: "Disconnect",
|
|
90
|
+
noActivity: "No recent activity.",
|
|
91
|
+
deleteAccount: "Delete account",
|
|
92
|
+
deleteAccountDescription: "Your account is disabled and you are signed out. An administrator can restore it.",
|
|
93
|
+
deleteAccountConfirm: "Delete my account",
|
|
94
|
+
loading: "Loading",
|
|
95
|
+
copied: "Copied",
|
|
96
|
+
copy: "Copy",
|
|
97
|
+
done: "Done",
|
|
98
|
+
errorGeneric: "Something went wrong. Please try again.",
|
|
99
|
+
errorInvalidCredentials: "Invalid email or password.",
|
|
100
|
+
errorUserExists: "An account with this email already exists.",
|
|
101
|
+
errorUserBlocked: "This account is blocked. Contact support.",
|
|
102
|
+
errorRateLimit: "Too many attempts. Wait a moment and try again.",
|
|
103
|
+
errorInvalidToken: "This link is invalid or has expired. Request a new one.",
|
|
104
|
+
errorInvalidCode: "That code is not valid. Check it and try again.",
|
|
105
|
+
errorPasswordMismatch: "Passwords do not match.",
|
|
106
|
+
errorPasswordRecentlyUsed: "You used this password recently. Choose a different one.",
|
|
107
|
+
errorPasswordPersonalData: "Password must not contain your name, email or phone.",
|
|
108
|
+
errorPasswordWeak: "Password is too common or too short. Use at least 8 characters.",
|
|
109
|
+
errorPasswordPwned: "This password appeared in a data breach. Choose a different one.",
|
|
110
|
+
errorChallengeRequired: "Confirm a second factor to continue.",
|
|
111
|
+
errorSessionExists: "You are already signed in.",
|
|
112
|
+
errorOAuth: "Sign in with the provider failed. Please try again.",
|
|
113
|
+
errorNetwork: "Could not reach the server. Check your connection.",
|
|
114
|
+
errorMethodDisabled: "This sign-in method is disabled for this project.",
|
|
115
|
+
errorNotConfigured: "Auth UI is not configured. Call AuthUI.init() or add <authui-config>.",
|
|
116
|
+
passwordHint: "At least 8 characters.",
|
|
117
|
+
signedInAs: "Signed in as",
|
|
118
|
+
manageAccount: "Manage account",
|
|
119
|
+
continue: "Continue",
|
|
120
|
+
provider: "Provider",
|
|
121
|
+
lastActive: "Last active",
|
|
122
|
+
guestAccount: "Guest account",
|
|
123
|
+
guestAccountDescription: "Add an email and password to keep your data."
|
|
124
|
+
};
|
|
125
|
+
function it(e, t = {}) {
|
|
126
|
+
return e.replace(
|
|
127
|
+
/\{(\w+)\}/g,
|
|
128
|
+
(i, r) => r in t ? String(t[r]) : `{${r}}`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
const st = {
|
|
132
|
+
amazon: "Amazon",
|
|
133
|
+
apple: "Apple",
|
|
134
|
+
appwrite: "Appwrite",
|
|
135
|
+
auth0: "Auth0",
|
|
136
|
+
authentik: "Authentik",
|
|
137
|
+
autodesk: "Autodesk",
|
|
138
|
+
bitbucket: "Bitbucket",
|
|
139
|
+
bitly: "Bitly",
|
|
140
|
+
box: "Box",
|
|
141
|
+
cloudflare: "Cloudflare",
|
|
142
|
+
dailymotion: "Dailymotion",
|
|
143
|
+
discord: "Discord",
|
|
144
|
+
disqus: "Disqus",
|
|
145
|
+
dropbox: "Dropbox",
|
|
146
|
+
etsy: "Etsy",
|
|
147
|
+
facebook: "Facebook",
|
|
148
|
+
figma: "Figma",
|
|
149
|
+
fusionauth: "FusionAuth",
|
|
150
|
+
github: "GitHub",
|
|
151
|
+
gitlab: "GitLab",
|
|
152
|
+
google: "Google",
|
|
153
|
+
huggingface: "Hugging Face",
|
|
154
|
+
kakao: "Kakao",
|
|
155
|
+
keycloak: "Keycloak",
|
|
156
|
+
kick: "Kick",
|
|
157
|
+
linkedin: "LinkedIn",
|
|
158
|
+
microsoft: "Microsoft",
|
|
159
|
+
notion: "Notion",
|
|
160
|
+
oidc: "OpenID Connect",
|
|
161
|
+
okta: "Okta",
|
|
162
|
+
paypal: "PayPal",
|
|
163
|
+
paypalSandbox: "PayPal Sandbox",
|
|
164
|
+
podio: "Podio",
|
|
165
|
+
resend: "Resend",
|
|
166
|
+
salesforce: "Salesforce",
|
|
167
|
+
slack: "Slack",
|
|
168
|
+
spotify: "Spotify",
|
|
169
|
+
stripe: "Stripe",
|
|
170
|
+
tiktok: "TikTok",
|
|
171
|
+
tradeshift: "Tradeshift",
|
|
172
|
+
tradeshiftBox: "Tradeshift Box",
|
|
173
|
+
twitch: "Twitch",
|
|
174
|
+
wordpress: "WordPress",
|
|
175
|
+
x: "X",
|
|
176
|
+
yahoo: "Yahoo",
|
|
177
|
+
yammer: "Yammer",
|
|
178
|
+
yandex: "Yandex",
|
|
179
|
+
zoho: "Zoho",
|
|
180
|
+
zoom: "Zoom"
|
|
181
|
+
};
|
|
182
|
+
function E(e) {
|
|
183
|
+
return st[e] ?? e.charAt(0).toUpperCase() + e.slice(1);
|
|
184
|
+
}
|
|
185
|
+
const b = {
|
|
186
|
+
moreFactorsRequired: "user_more_factors_required",
|
|
187
|
+
invalidCredentials: "user_invalid_credentials",
|
|
188
|
+
userAlreadyExists: "user_already_exists",
|
|
189
|
+
emailAlreadyExists: "user_email_already_exists",
|
|
190
|
+
phoneAlreadyExists: "user_phone_already_exists",
|
|
191
|
+
userBlocked: "user_blocked",
|
|
192
|
+
rateLimit: "general_rate_limit_exceeded",
|
|
193
|
+
invalidToken: "user_invalid_token",
|
|
194
|
+
invalidCode: "user_invalid_code",
|
|
195
|
+
passwordMismatch: "user_password_mismatch",
|
|
196
|
+
passwordRecentlyUsed: "password_recently_used",
|
|
197
|
+
passwordPersonalData: "password_personal_data",
|
|
198
|
+
passwordWeak: "user_password_weak",
|
|
199
|
+
passwordPwned: "password_pwned",
|
|
200
|
+
challengeRequired: "user_challenge_required",
|
|
201
|
+
recoveryCodesExist: "user_recovery_codes_already_exists",
|
|
202
|
+
recoveryCodesNotFound: "user_recovery_codes_not_found",
|
|
203
|
+
authenticatorNotFound: "user_authenticator_not_found",
|
|
204
|
+
routeNotFound: "general_route_not_found",
|
|
205
|
+
emailAlreadyVerified: "user_email_already_verified",
|
|
206
|
+
sessionNotFound: "user_session_not_found",
|
|
207
|
+
wafChallenged: "waf_request_challenged",
|
|
208
|
+
sessionAlreadyExists: "user_session_already_exists",
|
|
209
|
+
oauthUnauthorized: "user_oauth2_unauthorized",
|
|
210
|
+
oauthBadRequest: "user_oauth2_bad_request",
|
|
211
|
+
unauthorized: "general_unauthorized_scope",
|
|
212
|
+
userUnauthorized: "user_unauthorized",
|
|
213
|
+
authMethodUnsupported: "user_auth_method_unsupported",
|
|
214
|
+
countMaxExceeded: "user_count_exceeded",
|
|
215
|
+
targetAlreadyExists: "user_target_already_exists"
|
|
216
|
+
};
|
|
217
|
+
function _(e) {
|
|
218
|
+
if (e && typeof e == "object") {
|
|
219
|
+
const t = e;
|
|
220
|
+
return {
|
|
221
|
+
message: typeof t.message == "string" ? t.message : "Unknown error",
|
|
222
|
+
type: typeof t.type == "string" ? t.type : "",
|
|
223
|
+
code: typeof t.code == "number" ? t.code : 0
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return { message: String(e), type: "", code: 0 };
|
|
227
|
+
}
|
|
228
|
+
function F(e, t) {
|
|
229
|
+
return _(e).type === t;
|
|
230
|
+
}
|
|
231
|
+
function Z(e, t, i = "link") {
|
|
232
|
+
const r = _(e);
|
|
233
|
+
switch (r.type) {
|
|
234
|
+
case b.invalidCredentials:
|
|
235
|
+
return t.errorInvalidCredentials;
|
|
236
|
+
case b.userAlreadyExists:
|
|
237
|
+
case b.emailAlreadyExists:
|
|
238
|
+
case b.phoneAlreadyExists:
|
|
239
|
+
return t.errorUserExists;
|
|
240
|
+
case b.userBlocked:
|
|
241
|
+
return t.errorUserBlocked;
|
|
242
|
+
case b.rateLimit:
|
|
243
|
+
return t.errorRateLimit;
|
|
244
|
+
case b.invalidToken:
|
|
245
|
+
return i === "code" ? t.errorInvalidCode : t.errorInvalidToken;
|
|
246
|
+
case b.invalidCode:
|
|
247
|
+
return t.errorInvalidCode;
|
|
248
|
+
case b.passwordMismatch:
|
|
249
|
+
return t.errorPasswordMismatch;
|
|
250
|
+
case b.passwordRecentlyUsed:
|
|
251
|
+
return t.errorPasswordRecentlyUsed;
|
|
252
|
+
case b.passwordPersonalData:
|
|
253
|
+
return t.errorPasswordPersonalData;
|
|
254
|
+
case b.passwordWeak:
|
|
255
|
+
return t.errorPasswordWeak;
|
|
256
|
+
case b.passwordPwned:
|
|
257
|
+
return t.errorPasswordPwned;
|
|
258
|
+
case b.challengeRequired:
|
|
259
|
+
return t.errorChallengeRequired;
|
|
260
|
+
case b.sessionAlreadyExists:
|
|
261
|
+
return t.errorSessionExists;
|
|
262
|
+
case b.oauthUnauthorized:
|
|
263
|
+
case b.oauthBadRequest:
|
|
264
|
+
return t.errorOAuth;
|
|
265
|
+
case b.authMethodUnsupported:
|
|
266
|
+
return t.errorMethodDisabled;
|
|
267
|
+
}
|
|
268
|
+
return r.code === 0 && /fetch|network/i.test(r.message) ? t.errorNetwork : r.message || t.errorGeneric;
|
|
269
|
+
}
|
|
270
|
+
function k(e, t, i) {
|
|
271
|
+
for (const r of t) {
|
|
272
|
+
const a = e[r];
|
|
273
|
+
if (typeof a == "function")
|
|
274
|
+
return a.apply(e, i);
|
|
275
|
+
}
|
|
276
|
+
return Promise.reject(
|
|
277
|
+
new Error(`Appwrite SDK is missing ${t[0]}(). Update the appwrite package.`)
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
const D = "authui", N = ["userId", "secret", "expire", "project", "error", D], j = () => ({
|
|
281
|
+
status: "loading",
|
|
282
|
+
user: null,
|
|
283
|
+
mfaFactors: null,
|
|
284
|
+
pending: null,
|
|
285
|
+
configured: !1
|
|
286
|
+
});
|
|
287
|
+
class rt {
|
|
288
|
+
constructor() {
|
|
289
|
+
this.client = null, this.account = null, this.config = null, this.state = j(), this.listeners = /* @__PURE__ */ new Map(), this.refreshPromise = null;
|
|
290
|
+
}
|
|
291
|
+
// ───────────────────────────── configuration ─────────────────────────────
|
|
292
|
+
/** Configure the Appwrite client. Safe to call more than once; the last call wins. */
|
|
293
|
+
configure(t) {
|
|
294
|
+
this.config = t, this.client = new Q().setEndpoint(t.endpoint).setProject(t.project), this.account = new J(this.client), this.setState({ configured: !0, status: "loading" }), typeof window < "u" && this.handleRedirect().then(() => this.refresh());
|
|
295
|
+
}
|
|
296
|
+
get isConfigured() {
|
|
297
|
+
return this.config !== null;
|
|
298
|
+
}
|
|
299
|
+
getConfig() {
|
|
300
|
+
return this.config;
|
|
301
|
+
}
|
|
302
|
+
/** The configured Appwrite client, for apps that want to reuse it. */
|
|
303
|
+
getClient() {
|
|
304
|
+
return this.client;
|
|
305
|
+
}
|
|
306
|
+
getStrings() {
|
|
307
|
+
return { ...et, ...this.config?.strings ?? {} };
|
|
308
|
+
}
|
|
309
|
+
getState() {
|
|
310
|
+
return { ...this.state };
|
|
311
|
+
}
|
|
312
|
+
get user() {
|
|
313
|
+
return this.state.user;
|
|
314
|
+
}
|
|
315
|
+
// ─────────────────────────────── events ───────────────────────────────
|
|
316
|
+
on(t, i) {
|
|
317
|
+
let r = this.listeners.get(t);
|
|
318
|
+
return r || (r = /* @__PURE__ */ new Set(), this.listeners.set(t, r)), r.add(i), () => r.delete(i);
|
|
319
|
+
}
|
|
320
|
+
emit(t, i) {
|
|
321
|
+
this.listeners.get(t)?.forEach((r) => {
|
|
322
|
+
try {
|
|
323
|
+
r(i);
|
|
324
|
+
} catch (a) {
|
|
325
|
+
console.error("[authui] listener failed", a);
|
|
326
|
+
}
|
|
327
|
+
}), typeof window < "u" && window.dispatchEvent(new CustomEvent(`authui:${t}`, { detail: i }));
|
|
328
|
+
}
|
|
329
|
+
setState(t) {
|
|
330
|
+
this.state = { ...this.state, ...t }, this.emit("change", this.getState());
|
|
331
|
+
}
|
|
332
|
+
fail(t) {
|
|
333
|
+
const i = _(t);
|
|
334
|
+
throw this.emit("error", i), t;
|
|
335
|
+
}
|
|
336
|
+
acct() {
|
|
337
|
+
if (!this.account) throw new Error(this.getStrings().errorNotConfigured);
|
|
338
|
+
return this.account;
|
|
339
|
+
}
|
|
340
|
+
// ─────────────────────────── session lifecycle ───────────────────────────
|
|
341
|
+
/** Re-fetch the current user and derive status. */
|
|
342
|
+
refresh() {
|
|
343
|
+
return this.refreshPromise ? this.refreshPromise : (this.refreshPromise = (async () => {
|
|
344
|
+
if (!this.account) {
|
|
345
|
+
this.setState({ status: "signed-out", user: null, mfaFactors: null });
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const t = this.state.status === "signed-in";
|
|
349
|
+
try {
|
|
350
|
+
const i = await this.account.get();
|
|
351
|
+
this.setState({ status: "signed-in", user: i, mfaFactors: null }), t || this.emit("signed-in", i);
|
|
352
|
+
} catch (i) {
|
|
353
|
+
if (F(i, b.moreFactorsRequired)) {
|
|
354
|
+
let r = null;
|
|
355
|
+
try {
|
|
356
|
+
r = await k(
|
|
357
|
+
this.account,
|
|
358
|
+
["listMFAFactors", "listMfaFactors"],
|
|
359
|
+
[]
|
|
360
|
+
);
|
|
361
|
+
} catch {
|
|
362
|
+
}
|
|
363
|
+
this.setState({ status: "mfa-required", user: null, mfaFactors: r });
|
|
364
|
+
} else
|
|
365
|
+
this.setState({ status: "signed-out", user: null, mfaFactors: null }), t && this.emit("signed-out", void 0);
|
|
366
|
+
}
|
|
367
|
+
})().finally(() => {
|
|
368
|
+
this.refreshPromise = null;
|
|
369
|
+
}), this.refreshPromise);
|
|
370
|
+
}
|
|
371
|
+
async afterSignIn() {
|
|
372
|
+
await this.refresh();
|
|
373
|
+
const t = this.config?.successUrl;
|
|
374
|
+
t && this.state.status === "signed-in" && typeof window < "u" && window.location.assign(t);
|
|
375
|
+
}
|
|
376
|
+
// ─────────────────────────────── sign in ───────────────────────────────
|
|
377
|
+
async signInWithEmailPassword(t, i) {
|
|
378
|
+
try {
|
|
379
|
+
await this.acct().createEmailPasswordSession(t.trim(), i);
|
|
380
|
+
} catch (r) {
|
|
381
|
+
this.fail(r);
|
|
382
|
+
}
|
|
383
|
+
await this.afterSignIn();
|
|
384
|
+
}
|
|
385
|
+
async signUp(t, i, r) {
|
|
386
|
+
try {
|
|
387
|
+
await this.acct().create(z.unique(), t.trim(), i, r?.trim() || void 0), await this.acct().createEmailPasswordSession(t.trim(), i);
|
|
388
|
+
} catch (a) {
|
|
389
|
+
this.fail(a);
|
|
390
|
+
}
|
|
391
|
+
await this.afterSignIn();
|
|
392
|
+
}
|
|
393
|
+
async signInAnonymously() {
|
|
394
|
+
try {
|
|
395
|
+
await this.acct().createAnonymousSession();
|
|
396
|
+
} catch (t) {
|
|
397
|
+
this.fail(t);
|
|
398
|
+
}
|
|
399
|
+
await this.afterSignIn();
|
|
400
|
+
}
|
|
401
|
+
/** Redirects the browser to the provider. Never resolves in a browser. */
|
|
402
|
+
signInWithOAuth(t) {
|
|
403
|
+
const i = this.config?.oauthScopes?.[t];
|
|
404
|
+
try {
|
|
405
|
+
this.acct().createOAuth2Token(
|
|
406
|
+
t,
|
|
407
|
+
this.redirectUrl("oauth"),
|
|
408
|
+
this.redirectUrl("oauth-failed"),
|
|
409
|
+
i
|
|
410
|
+
);
|
|
411
|
+
} catch (r) {
|
|
412
|
+
this.fail(r);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
async sendMagicUrl(t) {
|
|
416
|
+
try {
|
|
417
|
+
return await this.acct().createMagicURLToken(
|
|
418
|
+
z.unique(),
|
|
419
|
+
t.trim(),
|
|
420
|
+
this.redirectUrl("magic-url"),
|
|
421
|
+
this.config?.securityPhrase ?? !0
|
|
422
|
+
);
|
|
423
|
+
} catch (i) {
|
|
424
|
+
return this.fail(i);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
async sendEmailOtp(t) {
|
|
428
|
+
try {
|
|
429
|
+
return await this.acct().createEmailToken(
|
|
430
|
+
z.unique(),
|
|
431
|
+
t.trim(),
|
|
432
|
+
this.config?.securityPhrase ?? !0
|
|
433
|
+
);
|
|
434
|
+
} catch (i) {
|
|
435
|
+
return this.fail(i);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
async sendPhoneOtp(t) {
|
|
439
|
+
try {
|
|
440
|
+
return await this.acct().createPhoneToken(z.unique(), t.replace(/[\s()-]/g, ""));
|
|
441
|
+
} catch (i) {
|
|
442
|
+
return this.fail(i);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/** Redeem any token secret (email OTP, SMS OTP, magic URL, OAuth token). */
|
|
446
|
+
async signInWithToken(t, i) {
|
|
447
|
+
try {
|
|
448
|
+
await this.acct().createSession(t, i.trim());
|
|
449
|
+
} catch (r) {
|
|
450
|
+
this.fail(r);
|
|
451
|
+
}
|
|
452
|
+
await this.afterSignIn();
|
|
453
|
+
}
|
|
454
|
+
// ─────────────────────────────── MFA ───────────────────────────────
|
|
455
|
+
async createMfaChallenge(t) {
|
|
456
|
+
try {
|
|
457
|
+
return await k(
|
|
458
|
+
this.acct(),
|
|
459
|
+
["createMFAChallenge", "createMfaChallenge"],
|
|
460
|
+
[t]
|
|
461
|
+
);
|
|
462
|
+
} catch (i) {
|
|
463
|
+
return this.fail(i);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/** Verify a challenge. Completes a pending sign in, or acts as a step-up for protected actions. */
|
|
467
|
+
async completeMfaChallenge(t, i, r = {}) {
|
|
468
|
+
try {
|
|
469
|
+
await k(
|
|
470
|
+
this.acct(),
|
|
471
|
+
["updateMFAChallenge", "updateMfaChallenge"],
|
|
472
|
+
[t, i.trim()]
|
|
473
|
+
);
|
|
474
|
+
} catch (a) {
|
|
475
|
+
this.fail(a);
|
|
476
|
+
}
|
|
477
|
+
(r.signIn ?? !0) && await this.afterSignIn();
|
|
478
|
+
}
|
|
479
|
+
async listMfaFactors() {
|
|
480
|
+
try {
|
|
481
|
+
return await k(this.acct(), ["listMFAFactors", "listMfaFactors"], []);
|
|
482
|
+
} catch (t) {
|
|
483
|
+
return this.fail(t);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
async setMfaEnabled(t) {
|
|
487
|
+
try {
|
|
488
|
+
await this.acct().updateMFA(t);
|
|
489
|
+
} catch (i) {
|
|
490
|
+
this.fail(i);
|
|
491
|
+
}
|
|
492
|
+
await this.refresh();
|
|
493
|
+
}
|
|
494
|
+
async addAuthenticator() {
|
|
495
|
+
try {
|
|
496
|
+
return await k(
|
|
497
|
+
this.acct(),
|
|
498
|
+
["createMFAAuthenticator", "createMfaAuthenticator"],
|
|
499
|
+
["totp"]
|
|
500
|
+
);
|
|
501
|
+
} catch (t) {
|
|
502
|
+
return this.fail(t);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
async verifyAuthenticator(t) {
|
|
506
|
+
try {
|
|
507
|
+
await k(
|
|
508
|
+
this.acct(),
|
|
509
|
+
["updateMFAAuthenticator", "updateMfaAuthenticator"],
|
|
510
|
+
["totp", t.trim()]
|
|
511
|
+
);
|
|
512
|
+
} catch (i) {
|
|
513
|
+
this.fail(i);
|
|
514
|
+
}
|
|
515
|
+
await this.refresh();
|
|
516
|
+
}
|
|
517
|
+
/** Requires a recent MFA challenge (server rejects with user_challenge_required otherwise). */
|
|
518
|
+
async removeAuthenticator() {
|
|
519
|
+
try {
|
|
520
|
+
await k(this.acct(), ["deleteMFAAuthenticator", "deleteMfaAuthenticator"], ["totp"]);
|
|
521
|
+
} catch (t) {
|
|
522
|
+
this.fail(t);
|
|
523
|
+
}
|
|
524
|
+
await this.refresh();
|
|
525
|
+
}
|
|
526
|
+
async createRecoveryCodes() {
|
|
527
|
+
try {
|
|
528
|
+
return (await k(
|
|
529
|
+
this.acct(),
|
|
530
|
+
["createMFARecoveryCodes", "createMfaRecoveryCodes"],
|
|
531
|
+
[]
|
|
532
|
+
)).recoveryCodes;
|
|
533
|
+
} catch (t) {
|
|
534
|
+
return this.fail(t);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/** Requires a recent MFA challenge. */
|
|
538
|
+
async regenerateRecoveryCodes() {
|
|
539
|
+
try {
|
|
540
|
+
return (await k(
|
|
541
|
+
this.acct(),
|
|
542
|
+
["updateMFARecoveryCodes", "updateMfaRecoveryCodes"],
|
|
543
|
+
[]
|
|
544
|
+
)).recoveryCodes;
|
|
545
|
+
} catch (t) {
|
|
546
|
+
return this.fail(t);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
/** Requires a recent MFA challenge. */
|
|
550
|
+
async getRecoveryCodes() {
|
|
551
|
+
try {
|
|
552
|
+
return (await k(
|
|
553
|
+
this.acct(),
|
|
554
|
+
["getMFARecoveryCodes", "getMfaRecoveryCodes"],
|
|
555
|
+
[]
|
|
556
|
+
)).recoveryCodes;
|
|
557
|
+
} catch (t) {
|
|
558
|
+
return this.fail(t);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
// ───────────────────────── password recovery ─────────────────────────
|
|
562
|
+
async sendPasswordRecovery(t) {
|
|
563
|
+
try {
|
|
564
|
+
await this.acct().createRecovery(t.trim(), this.redirectUrl("recovery"));
|
|
565
|
+
} catch (i) {
|
|
566
|
+
this.fail(i);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
async completePasswordRecovery(t, i, r) {
|
|
570
|
+
try {
|
|
571
|
+
await this.acct().updateRecovery(t, i, r);
|
|
572
|
+
} catch (a) {
|
|
573
|
+
this.fail(a);
|
|
574
|
+
}
|
|
575
|
+
this.setState({ pending: null });
|
|
576
|
+
}
|
|
577
|
+
// ───────────────────────────── sign out ─────────────────────────────
|
|
578
|
+
async signOut(t = "current") {
|
|
579
|
+
try {
|
|
580
|
+
await this.acct().deleteSession(t);
|
|
581
|
+
} catch (i) {
|
|
582
|
+
this.fail(i);
|
|
583
|
+
}
|
|
584
|
+
t === "current" && (this.setState({ status: "signed-out", user: null, mfaFactors: null }), this.emit("signed-out", void 0));
|
|
585
|
+
}
|
|
586
|
+
async signOutEverywhere() {
|
|
587
|
+
try {
|
|
588
|
+
await this.acct().deleteSessions();
|
|
589
|
+
} catch (t) {
|
|
590
|
+
this.fail(t);
|
|
591
|
+
}
|
|
592
|
+
this.setState({ status: "signed-out", user: null, mfaFactors: null }), this.emit("signed-out", void 0);
|
|
593
|
+
}
|
|
594
|
+
// ────────────────────────── account management ──────────────────────────
|
|
595
|
+
async listSessions() {
|
|
596
|
+
try {
|
|
597
|
+
return (await this.acct().listSessions()).sessions;
|
|
598
|
+
} catch (t) {
|
|
599
|
+
return this.fail(t);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
async listIdentities() {
|
|
603
|
+
try {
|
|
604
|
+
return (await this.acct().listIdentities()).identities;
|
|
605
|
+
} catch (t) {
|
|
606
|
+
return this.fail(t);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async deleteIdentity(t) {
|
|
610
|
+
try {
|
|
611
|
+
await this.acct().deleteIdentity(t);
|
|
612
|
+
} catch (i) {
|
|
613
|
+
this.fail(i);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
async listLogs() {
|
|
617
|
+
try {
|
|
618
|
+
return (await this.acct().listLogs()).logs;
|
|
619
|
+
} catch (t) {
|
|
620
|
+
return this.fail(t);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
async updateName(t) {
|
|
624
|
+
try {
|
|
625
|
+
await this.acct().updateName(t.trim());
|
|
626
|
+
} catch (i) {
|
|
627
|
+
this.fail(i);
|
|
628
|
+
}
|
|
629
|
+
await this.refresh();
|
|
630
|
+
}
|
|
631
|
+
async updateEmail(t, i) {
|
|
632
|
+
try {
|
|
633
|
+
await this.acct().updateEmail(t.trim(), i);
|
|
634
|
+
} catch (r) {
|
|
635
|
+
this.fail(r);
|
|
636
|
+
}
|
|
637
|
+
await this.refresh();
|
|
638
|
+
}
|
|
639
|
+
async updatePhone(t, i) {
|
|
640
|
+
try {
|
|
641
|
+
await this.acct().updatePhone(t.replace(/[\s()-]/g, ""), i);
|
|
642
|
+
} catch (r) {
|
|
643
|
+
this.fail(r);
|
|
644
|
+
}
|
|
645
|
+
await this.refresh();
|
|
646
|
+
}
|
|
647
|
+
async updatePassword(t, i) {
|
|
648
|
+
try {
|
|
649
|
+
await this.acct().updatePassword(t, i || void 0);
|
|
650
|
+
} catch (r) {
|
|
651
|
+
this.fail(r);
|
|
652
|
+
}
|
|
653
|
+
await this.refresh();
|
|
654
|
+
}
|
|
655
|
+
/** Turn an anonymous session into a full account. */
|
|
656
|
+
async convertGuest(t, i, r) {
|
|
657
|
+
try {
|
|
658
|
+
await this.acct().updateEmail(t.trim(), i), r?.trim() && await this.acct().updateName(r.trim());
|
|
659
|
+
} catch (a) {
|
|
660
|
+
this.fail(a);
|
|
661
|
+
}
|
|
662
|
+
await this.refresh();
|
|
663
|
+
}
|
|
664
|
+
async sendEmailVerification() {
|
|
665
|
+
try {
|
|
666
|
+
await k(
|
|
667
|
+
this.acct(),
|
|
668
|
+
["createEmailVerification", "createVerification"],
|
|
669
|
+
[this.redirectUrl("verify-email")]
|
|
670
|
+
);
|
|
671
|
+
} catch (t) {
|
|
672
|
+
this.fail(t);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
async sendPhoneVerification() {
|
|
676
|
+
try {
|
|
677
|
+
await this.acct().createPhoneVerification();
|
|
678
|
+
} catch (t) {
|
|
679
|
+
this.fail(t);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
async confirmPhoneVerification(t) {
|
|
683
|
+
const i = this.state.user?.$id;
|
|
684
|
+
if (i) {
|
|
685
|
+
try {
|
|
686
|
+
await this.acct().updatePhoneVerification(i, t.trim());
|
|
687
|
+
} catch (r) {
|
|
688
|
+
this.fail(r);
|
|
689
|
+
}
|
|
690
|
+
await this.refresh();
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
/** Blocks the account and ends the session. Appwrite keeps the record so an admin can restore it. */
|
|
694
|
+
async deleteAccount() {
|
|
695
|
+
try {
|
|
696
|
+
await this.acct().updateStatus();
|
|
697
|
+
} catch (t) {
|
|
698
|
+
this.fail(t);
|
|
699
|
+
}
|
|
700
|
+
this.setState({ status: "signed-out", user: null, mfaFactors: null }), this.emit("signed-out", void 0);
|
|
701
|
+
}
|
|
702
|
+
// ───────────────────────────── redirects ─────────────────────────────
|
|
703
|
+
/** Build the URL Appwrite should send the user back to for a given flow. */
|
|
704
|
+
redirectUrl(t) {
|
|
705
|
+
const i = this.config?.redirectUrl ?? (typeof window < "u" ? window.location.origin + window.location.pathname : ""), r = new URL(i, typeof window < "u" ? window.location.href : void 0);
|
|
706
|
+
for (const a of N) r.searchParams.delete(a);
|
|
707
|
+
return r.searchParams.set(D, t), r.toString();
|
|
708
|
+
}
|
|
709
|
+
setPending(t) {
|
|
710
|
+
this.setState({ pending: t });
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Finish a flow that arrived through the URL. Called automatically by `configure()`.
|
|
714
|
+
* Returns true when a redirect was handled.
|
|
715
|
+
*/
|
|
716
|
+
async handleRedirect() {
|
|
717
|
+
if (typeof window > "u") return !1;
|
|
718
|
+
const t = new URLSearchParams(window.location.search), i = t.get(D);
|
|
719
|
+
if (!i) return !1;
|
|
720
|
+
const r = t.get("userId") ?? "", a = t.get("secret") ?? "";
|
|
721
|
+
this.cleanUrl();
|
|
722
|
+
try {
|
|
723
|
+
switch (i) {
|
|
724
|
+
case "oauth":
|
|
725
|
+
case "magic-url":
|
|
726
|
+
r && a && await this.acct().createSession(r, a);
|
|
727
|
+
break;
|
|
728
|
+
case "oauth-failed":
|
|
729
|
+
this.setState({ pending: { type: "oauth-failed" } });
|
|
730
|
+
break;
|
|
731
|
+
case "recovery":
|
|
732
|
+
r && a && this.setState({ pending: { type: "reset-password", userId: r, secret: a } });
|
|
733
|
+
break;
|
|
734
|
+
case "verify-email":
|
|
735
|
+
r && a && (await k(
|
|
736
|
+
this.acct(),
|
|
737
|
+
["updateEmailVerification", "updateVerification"],
|
|
738
|
+
[r, a]
|
|
739
|
+
), this.setState({
|
|
740
|
+
pending: {
|
|
741
|
+
type: "notice",
|
|
742
|
+
message: this.getStrings().emailVerified,
|
|
743
|
+
tone: "success"
|
|
744
|
+
}
|
|
745
|
+
}));
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
} catch (u) {
|
|
749
|
+
const h = _(u);
|
|
750
|
+
this.emit("error", h), this.setState({ pending: { type: "notice", message: h.message, tone: "error" } });
|
|
751
|
+
}
|
|
752
|
+
return !0;
|
|
753
|
+
}
|
|
754
|
+
cleanUrl() {
|
|
755
|
+
const t = new URL(window.location.href);
|
|
756
|
+
for (const i of N) t.searchParams.delete(i);
|
|
757
|
+
window.history.replaceState(window.history.state, "", t.toString());
|
|
758
|
+
}
|
|
759
|
+
/** Test helper. */
|
|
760
|
+
reset() {
|
|
761
|
+
this.client = null, this.account = null, this.config = null, this.state = j(), this.listeners.clear();
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
const o = new rt();
|
|
765
|
+
class at {
|
|
766
|
+
constructor() {
|
|
767
|
+
this.listeners = /* @__PURE__ */ new Set(), this.observer = null, this.media = null, this.notify = () => {
|
|
768
|
+
const t = this.isDark("auto");
|
|
769
|
+
this.listeners.forEach((i) => i(t));
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
isDark(t = "auto") {
|
|
773
|
+
if (t === "dark") return !0;
|
|
774
|
+
if (t === "light" || typeof document > "u") return !1;
|
|
775
|
+
const i = document.documentElement.classList;
|
|
776
|
+
return i.contains("dark") ? !0 : i.contains("light") ? !1 : document.documentElement.dataset.theme === "dark" ? !0 : document.documentElement.dataset.theme === "light" ? !1 : typeof window < "u" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
777
|
+
}
|
|
778
|
+
subscribe(t) {
|
|
779
|
+
return this.listeners.add(t), this.start(), () => {
|
|
780
|
+
this.listeners.delete(t), this.listeners.size === 0 && this.stop();
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
start() {
|
|
784
|
+
this.observer || typeof document > "u" || (this.observer = new MutationObserver(this.notify), this.observer.observe(document.documentElement, {
|
|
785
|
+
attributes: !0,
|
|
786
|
+
attributeFilter: ["class", "data-theme"]
|
|
787
|
+
}), typeof window < "u" && window.matchMedia && (this.media = window.matchMedia("(prefers-color-scheme: dark)"), this.media.addEventListener?.("change", this.notify)));
|
|
788
|
+
}
|
|
789
|
+
stop() {
|
|
790
|
+
this.observer?.disconnect(), this.observer = null, this.media?.removeEventListener?.("change", this.notify), this.media = null;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
const W = new at(), G = {
|
|
794
|
+
none: "0px",
|
|
795
|
+
sm: "0.25rem",
|
|
796
|
+
md: "0.625rem",
|
|
797
|
+
lg: "0.875rem",
|
|
798
|
+
xl: "1.125rem",
|
|
799
|
+
full: "1.5rem"
|
|
800
|
+
}, ot = A`
|
|
801
|
+
:host {
|
|
802
|
+
/* Light theme (matches :root in the console) */
|
|
803
|
+
--authui-background: oklch(1 0 0);
|
|
804
|
+
--authui-foreground: oklch(0.141 0.005 285.823);
|
|
805
|
+
--authui-card: oklch(1 0 0);
|
|
806
|
+
--authui-card-foreground: oklch(0.141 0.005 285.823);
|
|
807
|
+
--authui-popover: oklch(1 0 0);
|
|
808
|
+
--authui-popover-foreground: oklch(0.141 0.005 285.823);
|
|
809
|
+
--authui-primary: oklch(0.21 0.006 285.885);
|
|
810
|
+
--authui-primary-foreground: oklch(0.985 0 0);
|
|
811
|
+
--authui-secondary: oklch(0.967 0.001 286.375);
|
|
812
|
+
--authui-secondary-foreground: oklch(0.21 0.006 285.885);
|
|
813
|
+
--authui-muted: oklch(0.967 0.001 286.375);
|
|
814
|
+
--authui-muted-foreground: oklch(0.552 0.016 285.938);
|
|
815
|
+
--authui-accent: oklch(0.967 0.001 286.375);
|
|
816
|
+
--authui-accent-foreground: oklch(0.21 0.006 285.885);
|
|
817
|
+
--authui-destructive: oklch(0.577 0.245 27.325);
|
|
818
|
+
--authui-destructive-foreground: oklch(0.577 0.245 27.325);
|
|
819
|
+
--authui-border: oklch(0.93 0.0035 286.32);
|
|
820
|
+
--authui-input: oklch(0.93 0.0035 286.32);
|
|
821
|
+
--authui-ring: oklch(0.898 0.004 286.286);
|
|
822
|
+
--authui-brand: #fd366e;
|
|
823
|
+
--authui-brand-foreground: #ffffff;
|
|
824
|
+
--authui-success: oklch(0.696 0.17 162.48);
|
|
825
|
+
--authui-success-foreground: #047857;
|
|
826
|
+
--authui-success-bg: rgba(16, 185, 129, 0.1);
|
|
827
|
+
--authui-warning-foreground: #b45309;
|
|
828
|
+
--authui-warning-bg: rgba(245, 158, 11, 0.1);
|
|
829
|
+
--authui-error-foreground: #dc2626;
|
|
830
|
+
--authui-error-bg: rgba(239, 68, 68, 0.1);
|
|
831
|
+
--authui-info-foreground: #475569;
|
|
832
|
+
--authui-info-bg: rgba(100, 116, 139, 0.1);
|
|
833
|
+
--authui-overlay: rgba(0, 0, 0, 0.5);
|
|
834
|
+
|
|
835
|
+
--authui-radius: 0.625rem;
|
|
836
|
+
--authui-radius-sm: calc(var(--authui-radius) - 4px);
|
|
837
|
+
--authui-radius-md: calc(var(--authui-radius) - 2px);
|
|
838
|
+
--authui-radius-lg: var(--authui-radius);
|
|
839
|
+
--authui-radius-xl: calc(var(--authui-radius) + 4px);
|
|
840
|
+
|
|
841
|
+
--authui-font:
|
|
842
|
+
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans",
|
|
843
|
+
"Droid Sans", "Helvetica Neue", sans-serif;
|
|
844
|
+
--authui-font-mono: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
|
845
|
+
|
|
846
|
+
--authui-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
|
|
847
|
+
--authui-z: 110;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
:host([data-theme="dark"]) {
|
|
851
|
+
--authui-background: #19191c;
|
|
852
|
+
--authui-foreground: oklch(0.985 0 0);
|
|
853
|
+
--authui-card: #1d1d21;
|
|
854
|
+
--authui-card-foreground: oklch(0.985 0 0);
|
|
855
|
+
--authui-popover: #1d1d21;
|
|
856
|
+
--authui-popover-foreground: oklch(0.985 0 0);
|
|
857
|
+
--authui-primary: oklch(0.985 0 0);
|
|
858
|
+
--authui-primary-foreground: oklch(0.21 0.006 285.885);
|
|
859
|
+
--authui-secondary: #2d2d31;
|
|
860
|
+
--authui-secondary-foreground: oklch(0.985 0 0);
|
|
861
|
+
--authui-muted: #2d2d31;
|
|
862
|
+
--authui-muted-foreground: oklch(0.705 0.015 286.067);
|
|
863
|
+
--authui-accent: #2d2d31;
|
|
864
|
+
--authui-accent-foreground: oklch(0.985 0 0);
|
|
865
|
+
--authui-destructive: oklch(0.396 0.141 25.723);
|
|
866
|
+
--authui-destructive-foreground: oklch(0.637 0.237 25.331);
|
|
867
|
+
--authui-border: oklch(0.252 0.005 286.32);
|
|
868
|
+
--authui-input: #2d2d31;
|
|
869
|
+
--authui-ring: oklch(0.448 0.015 285.786);
|
|
870
|
+
--authui-success-foreground: #34d399;
|
|
871
|
+
--authui-warning-foreground: #fbbf24;
|
|
872
|
+
--authui-error-foreground: #f87171;
|
|
873
|
+
--authui-info-foreground: #94a3b8;
|
|
874
|
+
--authui-overlay: rgba(0, 0, 0, 0.6);
|
|
875
|
+
--authui-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.5);
|
|
876
|
+
color-scheme: dark;
|
|
877
|
+
}
|
|
878
|
+
`, nt = A`
|
|
879
|
+
*,
|
|
880
|
+
*::before,
|
|
881
|
+
*::after {
|
|
882
|
+
box-sizing: border-box;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
:host {
|
|
886
|
+
font-family: var(--authui-font);
|
|
887
|
+
color: var(--authui-foreground);
|
|
888
|
+
font-size: 14px;
|
|
889
|
+
line-height: 1.5;
|
|
890
|
+
-webkit-font-smoothing: antialiased;
|
|
891
|
+
-moz-osx-font-smoothing: grayscale;
|
|
892
|
+
text-align: start;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
[hidden] {
|
|
896
|
+
display: none !important;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
.sr-only {
|
|
900
|
+
position: absolute;
|
|
901
|
+
width: 1px;
|
|
902
|
+
height: 1px;
|
|
903
|
+
padding: 0;
|
|
904
|
+
margin: -1px;
|
|
905
|
+
overflow: hidden;
|
|
906
|
+
clip: rect(0, 0, 0, 0);
|
|
907
|
+
white-space: nowrap;
|
|
908
|
+
border: 0;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/* ── Typography ── */
|
|
912
|
+
.title {
|
|
913
|
+
font-size: 18px;
|
|
914
|
+
line-height: 1.2;
|
|
915
|
+
font-weight: 600;
|
|
916
|
+
letter-spacing: -0.01em;
|
|
917
|
+
margin: 0;
|
|
918
|
+
color: var(--authui-foreground);
|
|
919
|
+
}
|
|
920
|
+
.description {
|
|
921
|
+
font-size: 13px;
|
|
922
|
+
color: var(--authui-muted-foreground);
|
|
923
|
+
margin: 6px 0 0;
|
|
924
|
+
}
|
|
925
|
+
.eyebrow {
|
|
926
|
+
font-size: 12px;
|
|
927
|
+
font-weight: 600;
|
|
928
|
+
text-transform: uppercase;
|
|
929
|
+
letter-spacing: 0.08em;
|
|
930
|
+
color: var(--authui-muted-foreground);
|
|
931
|
+
}
|
|
932
|
+
.muted {
|
|
933
|
+
color: var(--authui-muted-foreground);
|
|
934
|
+
}
|
|
935
|
+
.small {
|
|
936
|
+
font-size: 13px;
|
|
937
|
+
}
|
|
938
|
+
.mono {
|
|
939
|
+
font-family: var(--authui-font-mono);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/* ── Button ── */
|
|
943
|
+
.btn {
|
|
944
|
+
display: inline-flex;
|
|
945
|
+
align-items: center;
|
|
946
|
+
justify-content: center;
|
|
947
|
+
gap: 6px;
|
|
948
|
+
white-space: nowrap;
|
|
949
|
+
border-radius: var(--authui-radius-md);
|
|
950
|
+
font-size: 14px;
|
|
951
|
+
font-weight: 500;
|
|
952
|
+
font-family: inherit;
|
|
953
|
+
height: 36px;
|
|
954
|
+
padding: 0 16px;
|
|
955
|
+
border: 1px solid transparent;
|
|
956
|
+
cursor: pointer;
|
|
957
|
+
transition:
|
|
958
|
+
background-color 150ms,
|
|
959
|
+
color 150ms,
|
|
960
|
+
border-color 150ms,
|
|
961
|
+
box-shadow 150ms,
|
|
962
|
+
opacity 150ms;
|
|
963
|
+
outline: none;
|
|
964
|
+
flex-shrink: 0;
|
|
965
|
+
text-decoration: none;
|
|
966
|
+
position: relative;
|
|
967
|
+
}
|
|
968
|
+
.btn:focus-visible {
|
|
969
|
+
border-color: var(--authui-ring);
|
|
970
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--authui-ring) 50%, transparent);
|
|
971
|
+
}
|
|
972
|
+
.btn:disabled,
|
|
973
|
+
.btn[aria-disabled="true"] {
|
|
974
|
+
pointer-events: none;
|
|
975
|
+
opacity: 0.5;
|
|
976
|
+
}
|
|
977
|
+
.btn svg {
|
|
978
|
+
width: 16px;
|
|
979
|
+
height: 16px;
|
|
980
|
+
flex-shrink: 0;
|
|
981
|
+
pointer-events: none;
|
|
982
|
+
}
|
|
983
|
+
.btn-primary {
|
|
984
|
+
background: var(--authui-primary);
|
|
985
|
+
color: var(--authui-primary-foreground);
|
|
986
|
+
}
|
|
987
|
+
.btn-primary:hover {
|
|
988
|
+
background: color-mix(in oklab, var(--authui-primary) 90%, transparent);
|
|
989
|
+
}
|
|
990
|
+
.btn-brand {
|
|
991
|
+
background: var(--authui-brand);
|
|
992
|
+
color: var(--authui-brand-foreground);
|
|
993
|
+
}
|
|
994
|
+
.btn-brand:hover {
|
|
995
|
+
opacity: 0.9;
|
|
996
|
+
}
|
|
997
|
+
.btn-outline {
|
|
998
|
+
border-color: var(--authui-border);
|
|
999
|
+
background: transparent;
|
|
1000
|
+
color: var(--authui-foreground);
|
|
1001
|
+
}
|
|
1002
|
+
.btn-outline:hover {
|
|
1003
|
+
background: var(--authui-accent);
|
|
1004
|
+
color: var(--authui-accent-foreground);
|
|
1005
|
+
}
|
|
1006
|
+
.btn-secondary {
|
|
1007
|
+
background: var(--authui-secondary);
|
|
1008
|
+
color: var(--authui-secondary-foreground);
|
|
1009
|
+
}
|
|
1010
|
+
.btn-secondary:hover {
|
|
1011
|
+
background: color-mix(in oklab, var(--authui-secondary) 80%, transparent);
|
|
1012
|
+
}
|
|
1013
|
+
.btn-ghost {
|
|
1014
|
+
background: transparent;
|
|
1015
|
+
color: var(--authui-muted-foreground);
|
|
1016
|
+
}
|
|
1017
|
+
.btn-ghost:hover {
|
|
1018
|
+
background: var(--authui-accent);
|
|
1019
|
+
color: var(--authui-foreground);
|
|
1020
|
+
}
|
|
1021
|
+
.btn-destructive {
|
|
1022
|
+
background: var(--authui-destructive);
|
|
1023
|
+
color: #fff;
|
|
1024
|
+
}
|
|
1025
|
+
.btn-destructive:hover {
|
|
1026
|
+
background: color-mix(in oklab, var(--authui-destructive) 90%, transparent);
|
|
1027
|
+
}
|
|
1028
|
+
.btn-link {
|
|
1029
|
+
height: auto;
|
|
1030
|
+
padding: 0;
|
|
1031
|
+
border: 0;
|
|
1032
|
+
background: none;
|
|
1033
|
+
font-weight: 500;
|
|
1034
|
+
color: color-mix(in oklab, var(--authui-foreground) 85%, transparent);
|
|
1035
|
+
text-decoration: underline;
|
|
1036
|
+
text-decoration-style: dotted;
|
|
1037
|
+
text-decoration-color: color-mix(in oklab, var(--authui-muted-foreground) 38%, transparent);
|
|
1038
|
+
text-underline-offset: 3px;
|
|
1039
|
+
text-decoration-thickness: 1px;
|
|
1040
|
+
border-radius: 2px;
|
|
1041
|
+
}
|
|
1042
|
+
.btn-link:hover {
|
|
1043
|
+
color: var(--authui-foreground);
|
|
1044
|
+
text-decoration-color: color-mix(in oklab, var(--authui-muted-foreground) 58%, transparent);
|
|
1045
|
+
}
|
|
1046
|
+
.btn-sm {
|
|
1047
|
+
height: 32px;
|
|
1048
|
+
padding: 0 12px;
|
|
1049
|
+
font-size: 13px;
|
|
1050
|
+
}
|
|
1051
|
+
.btn-lg {
|
|
1052
|
+
height: 40px;
|
|
1053
|
+
padding: 0 24px;
|
|
1054
|
+
}
|
|
1055
|
+
.btn-icon {
|
|
1056
|
+
width: 36px;
|
|
1057
|
+
height: 36px;
|
|
1058
|
+
padding: 0;
|
|
1059
|
+
}
|
|
1060
|
+
.btn-block {
|
|
1061
|
+
width: 100%;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
/* ── Form ── */
|
|
1065
|
+
.field {
|
|
1066
|
+
display: flex;
|
|
1067
|
+
flex-direction: column;
|
|
1068
|
+
gap: 6px;
|
|
1069
|
+
}
|
|
1070
|
+
.label {
|
|
1071
|
+
display: flex;
|
|
1072
|
+
align-items: center;
|
|
1073
|
+
justify-content: space-between;
|
|
1074
|
+
gap: 8px;
|
|
1075
|
+
font-size: 14px;
|
|
1076
|
+
line-height: 1;
|
|
1077
|
+
font-weight: 500;
|
|
1078
|
+
user-select: none;
|
|
1079
|
+
}
|
|
1080
|
+
.input {
|
|
1081
|
+
font: inherit;
|
|
1082
|
+
font-size: 14px;
|
|
1083
|
+
height: 36px;
|
|
1084
|
+
width: 100%;
|
|
1085
|
+
min-width: 0;
|
|
1086
|
+
border-radius: var(--authui-radius-md);
|
|
1087
|
+
border: 1px solid var(--authui-input);
|
|
1088
|
+
background: transparent;
|
|
1089
|
+
color: var(--authui-foreground);
|
|
1090
|
+
padding: 4px 12px;
|
|
1091
|
+
outline: none;
|
|
1092
|
+
transition:
|
|
1093
|
+
border-color 150ms,
|
|
1094
|
+
box-shadow 150ms;
|
|
1095
|
+
}
|
|
1096
|
+
:host([data-theme="dark"]) .input {
|
|
1097
|
+
background: color-mix(in oklab, var(--authui-input) 30%, transparent);
|
|
1098
|
+
}
|
|
1099
|
+
.input::placeholder {
|
|
1100
|
+
color: var(--authui-muted-foreground);
|
|
1101
|
+
}
|
|
1102
|
+
.input:focus-visible {
|
|
1103
|
+
border-color: var(--authui-ring);
|
|
1104
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--authui-ring) 50%, transparent);
|
|
1105
|
+
}
|
|
1106
|
+
.input[aria-invalid="true"] {
|
|
1107
|
+
border-color: var(--authui-destructive);
|
|
1108
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--authui-destructive) 20%, transparent);
|
|
1109
|
+
}
|
|
1110
|
+
.input:disabled {
|
|
1111
|
+
opacity: 0.5;
|
|
1112
|
+
cursor: not-allowed;
|
|
1113
|
+
}
|
|
1114
|
+
.input-wrap {
|
|
1115
|
+
position: relative;
|
|
1116
|
+
display: flex;
|
|
1117
|
+
align-items: center;
|
|
1118
|
+
}
|
|
1119
|
+
.input-wrap .input {
|
|
1120
|
+
padding-inline-end: 40px;
|
|
1121
|
+
}
|
|
1122
|
+
.input-wrap .btn-icon {
|
|
1123
|
+
position: absolute;
|
|
1124
|
+
inset-inline-end: 2px;
|
|
1125
|
+
width: 32px;
|
|
1126
|
+
height: 32px;
|
|
1127
|
+
color: var(--authui-muted-foreground);
|
|
1128
|
+
}
|
|
1129
|
+
.input-otp {
|
|
1130
|
+
letter-spacing: 0.4em;
|
|
1131
|
+
text-align: center;
|
|
1132
|
+
font-family: var(--authui-font-mono);
|
|
1133
|
+
font-size: 18px;
|
|
1134
|
+
height: 44px;
|
|
1135
|
+
}
|
|
1136
|
+
.hint {
|
|
1137
|
+
font-size: 12px;
|
|
1138
|
+
color: var(--authui-muted-foreground);
|
|
1139
|
+
margin: 0;
|
|
1140
|
+
}
|
|
1141
|
+
.form {
|
|
1142
|
+
display: flex;
|
|
1143
|
+
flex-direction: column;
|
|
1144
|
+
gap: 16px;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
/* ── Alert ── */
|
|
1148
|
+
.alert {
|
|
1149
|
+
position: relative;
|
|
1150
|
+
width: 100%;
|
|
1151
|
+
border-radius: var(--authui-radius-lg);
|
|
1152
|
+
border: 1px solid var(--authui-border);
|
|
1153
|
+
padding: 12px 16px;
|
|
1154
|
+
font-size: 13px;
|
|
1155
|
+
display: grid;
|
|
1156
|
+
grid-template-columns: 16px 1fr;
|
|
1157
|
+
column-gap: 12px;
|
|
1158
|
+
row-gap: 2px;
|
|
1159
|
+
align-items: start;
|
|
1160
|
+
background: var(--authui-card);
|
|
1161
|
+
color: var(--authui-card-foreground);
|
|
1162
|
+
}
|
|
1163
|
+
.alert svg {
|
|
1164
|
+
width: 16px;
|
|
1165
|
+
height: 16px;
|
|
1166
|
+
margin-top: 2px;
|
|
1167
|
+
}
|
|
1168
|
+
.alert-title {
|
|
1169
|
+
grid-column: 2;
|
|
1170
|
+
font-weight: 500;
|
|
1171
|
+
letter-spacing: -0.01em;
|
|
1172
|
+
}
|
|
1173
|
+
.alert-body {
|
|
1174
|
+
grid-column: 2;
|
|
1175
|
+
color: var(--authui-muted-foreground);
|
|
1176
|
+
line-height: 1.55;
|
|
1177
|
+
}
|
|
1178
|
+
.alert-error {
|
|
1179
|
+
color: var(--authui-error-foreground);
|
|
1180
|
+
border-color: color-mix(in oklab, var(--authui-error-foreground) 30%, transparent);
|
|
1181
|
+
background: var(--authui-error-bg);
|
|
1182
|
+
}
|
|
1183
|
+
.alert-error .alert-body {
|
|
1184
|
+
color: color-mix(in oklab, var(--authui-error-foreground) 90%, transparent);
|
|
1185
|
+
}
|
|
1186
|
+
.alert-success {
|
|
1187
|
+
color: var(--authui-success-foreground);
|
|
1188
|
+
border-color: color-mix(in oklab, var(--authui-success-foreground) 30%, transparent);
|
|
1189
|
+
background: var(--authui-success-bg);
|
|
1190
|
+
}
|
|
1191
|
+
.alert-success .alert-body {
|
|
1192
|
+
color: color-mix(in oklab, var(--authui-success-foreground) 90%, transparent);
|
|
1193
|
+
}
|
|
1194
|
+
.alert-info {
|
|
1195
|
+
background: var(--authui-info-bg);
|
|
1196
|
+
}
|
|
1197
|
+
.alert-warning {
|
|
1198
|
+
color: var(--authui-warning-foreground);
|
|
1199
|
+
border-color: color-mix(in oklab, var(--authui-warning-foreground) 30%, transparent);
|
|
1200
|
+
background: var(--authui-warning-bg);
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
/* ── Badge ── */
|
|
1204
|
+
.badge {
|
|
1205
|
+
display: inline-flex;
|
|
1206
|
+
align-items: center;
|
|
1207
|
+
justify-content: center;
|
|
1208
|
+
gap: 4px;
|
|
1209
|
+
border-radius: var(--authui-radius-md);
|
|
1210
|
+
padding: 2px 8px;
|
|
1211
|
+
font-size: 12px;
|
|
1212
|
+
font-weight: 500;
|
|
1213
|
+
white-space: nowrap;
|
|
1214
|
+
width: fit-content;
|
|
1215
|
+
}
|
|
1216
|
+
.badge svg {
|
|
1217
|
+
width: 12px;
|
|
1218
|
+
height: 12px;
|
|
1219
|
+
}
|
|
1220
|
+
.badge-success {
|
|
1221
|
+
background: var(--authui-success-bg);
|
|
1222
|
+
color: var(--authui-success-foreground);
|
|
1223
|
+
}
|
|
1224
|
+
.badge-error {
|
|
1225
|
+
background: var(--authui-error-bg);
|
|
1226
|
+
color: var(--authui-error-foreground);
|
|
1227
|
+
}
|
|
1228
|
+
.badge-warning {
|
|
1229
|
+
background: var(--authui-warning-bg);
|
|
1230
|
+
color: var(--authui-warning-foreground);
|
|
1231
|
+
}
|
|
1232
|
+
.badge-info {
|
|
1233
|
+
background: var(--authui-info-bg);
|
|
1234
|
+
color: var(--authui-info-foreground);
|
|
1235
|
+
}
|
|
1236
|
+
.badge-outline {
|
|
1237
|
+
background: color-mix(in oklab, var(--authui-muted) 60%, transparent);
|
|
1238
|
+
color: color-mix(in oklab, var(--authui-foreground) 80%, transparent);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
/* ── Separator ── */
|
|
1242
|
+
.separator {
|
|
1243
|
+
height: 1px;
|
|
1244
|
+
width: 100%;
|
|
1245
|
+
background: var(--authui-border);
|
|
1246
|
+
flex-shrink: 0;
|
|
1247
|
+
}
|
|
1248
|
+
.separator-text {
|
|
1249
|
+
display: flex;
|
|
1250
|
+
align-items: center;
|
|
1251
|
+
gap: 12px;
|
|
1252
|
+
font-size: 12px;
|
|
1253
|
+
color: var(--authui-muted-foreground);
|
|
1254
|
+
text-transform: uppercase;
|
|
1255
|
+
letter-spacing: 0.06em;
|
|
1256
|
+
}
|
|
1257
|
+
.separator-text::before,
|
|
1258
|
+
.separator-text::after {
|
|
1259
|
+
content: "";
|
|
1260
|
+
flex: 1;
|
|
1261
|
+
height: 1px;
|
|
1262
|
+
background: var(--authui-border);
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
/* ── Tabs ── */
|
|
1266
|
+
.tabs {
|
|
1267
|
+
display: inline-flex;
|
|
1268
|
+
align-items: center;
|
|
1269
|
+
justify-content: center;
|
|
1270
|
+
height: 36px;
|
|
1271
|
+
width: fit-content;
|
|
1272
|
+
max-width: 100%;
|
|
1273
|
+
overflow-x: auto;
|
|
1274
|
+
border-radius: var(--authui-radius-lg);
|
|
1275
|
+
background: color-mix(in oklab, var(--authui-muted) 50%, transparent);
|
|
1276
|
+
color: var(--authui-muted-foreground);
|
|
1277
|
+
padding: 3px;
|
|
1278
|
+
gap: 2px;
|
|
1279
|
+
scrollbar-width: none;
|
|
1280
|
+
}
|
|
1281
|
+
:host([data-theme="dark"]) .tabs {
|
|
1282
|
+
background: color-mix(in oklab, var(--authui-muted) 80%, transparent);
|
|
1283
|
+
}
|
|
1284
|
+
.tab {
|
|
1285
|
+
display: inline-flex;
|
|
1286
|
+
align-items: center;
|
|
1287
|
+
justify-content: center;
|
|
1288
|
+
gap: 6px;
|
|
1289
|
+
height: 100%;
|
|
1290
|
+
flex: 1;
|
|
1291
|
+
padding: 4px 10px;
|
|
1292
|
+
border-radius: var(--authui-radius-md);
|
|
1293
|
+
border: 1px solid transparent;
|
|
1294
|
+
background: transparent;
|
|
1295
|
+
color: var(--authui-muted-foreground);
|
|
1296
|
+
font: inherit;
|
|
1297
|
+
font-size: 13px;
|
|
1298
|
+
font-weight: 500;
|
|
1299
|
+
white-space: nowrap;
|
|
1300
|
+
cursor: pointer;
|
|
1301
|
+
transition:
|
|
1302
|
+
color 150ms,
|
|
1303
|
+
background-color 150ms,
|
|
1304
|
+
box-shadow 150ms;
|
|
1305
|
+
}
|
|
1306
|
+
.tab:hover {
|
|
1307
|
+
color: var(--authui-foreground);
|
|
1308
|
+
}
|
|
1309
|
+
.tab[aria-selected="true"] {
|
|
1310
|
+
background: var(--authui-background);
|
|
1311
|
+
color: var(--authui-foreground);
|
|
1312
|
+
border-color: var(--authui-input);
|
|
1313
|
+
}
|
|
1314
|
+
.tab:focus-visible {
|
|
1315
|
+
outline: none;
|
|
1316
|
+
box-shadow: inset 0 0 0 3px color-mix(in oklab, var(--authui-ring) 50%, transparent);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
/* ── Settings card (console "Settings Card Structure") ── */
|
|
1320
|
+
.card {
|
|
1321
|
+
border-radius: var(--authui-radius-xl);
|
|
1322
|
+
border: 1px solid var(--authui-border);
|
|
1323
|
+
background: color-mix(in oklab, var(--authui-card) 50%, transparent);
|
|
1324
|
+
overflow: hidden;
|
|
1325
|
+
}
|
|
1326
|
+
.card-header {
|
|
1327
|
+
padding: 16px 24px;
|
|
1328
|
+
}
|
|
1329
|
+
.card-title {
|
|
1330
|
+
font-size: 15px;
|
|
1331
|
+
font-weight: 600;
|
|
1332
|
+
margin: 0;
|
|
1333
|
+
color: var(--authui-foreground);
|
|
1334
|
+
}
|
|
1335
|
+
.card-description {
|
|
1336
|
+
font-size: 13px;
|
|
1337
|
+
color: var(--authui-muted-foreground);
|
|
1338
|
+
margin: 8px 0 0;
|
|
1339
|
+
}
|
|
1340
|
+
.card-body {
|
|
1341
|
+
padding: 16px 24px;
|
|
1342
|
+
border-top: 1px solid var(--authui-border);
|
|
1343
|
+
}
|
|
1344
|
+
.card-footer {
|
|
1345
|
+
padding: 16px 24px;
|
|
1346
|
+
border-top: 1px solid var(--authui-border);
|
|
1347
|
+
background: color-mix(in oklab, var(--authui-muted) 30%, transparent);
|
|
1348
|
+
display: flex;
|
|
1349
|
+
justify-content: flex-end;
|
|
1350
|
+
gap: 8px;
|
|
1351
|
+
}
|
|
1352
|
+
.card-danger {
|
|
1353
|
+
border-color: color-mix(in oklab, var(--authui-destructive) 40%, transparent);
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
/* ── Lists / rows ── */
|
|
1357
|
+
.row {
|
|
1358
|
+
display: flex;
|
|
1359
|
+
align-items: center;
|
|
1360
|
+
justify-content: space-between;
|
|
1361
|
+
gap: 12px;
|
|
1362
|
+
padding: 12px 0;
|
|
1363
|
+
}
|
|
1364
|
+
.row + .row {
|
|
1365
|
+
border-top: 1px solid var(--authui-border);
|
|
1366
|
+
}
|
|
1367
|
+
.row-main {
|
|
1368
|
+
display: flex;
|
|
1369
|
+
flex-direction: column;
|
|
1370
|
+
gap: 2px;
|
|
1371
|
+
min-width: 0;
|
|
1372
|
+
}
|
|
1373
|
+
.row-title {
|
|
1374
|
+
font-size: 14px;
|
|
1375
|
+
font-weight: 500;
|
|
1376
|
+
display: flex;
|
|
1377
|
+
align-items: center;
|
|
1378
|
+
gap: 8px;
|
|
1379
|
+
flex-wrap: wrap;
|
|
1380
|
+
}
|
|
1381
|
+
.row-sub {
|
|
1382
|
+
font-size: 12px;
|
|
1383
|
+
color: var(--authui-muted-foreground);
|
|
1384
|
+
overflow: hidden;
|
|
1385
|
+
text-overflow: ellipsis;
|
|
1386
|
+
white-space: nowrap;
|
|
1387
|
+
}
|
|
1388
|
+
.row-actions {
|
|
1389
|
+
display: flex;
|
|
1390
|
+
align-items: center;
|
|
1391
|
+
gap: 8px;
|
|
1392
|
+
flex-shrink: 0;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
/* ── Misc ── */
|
|
1396
|
+
.stack {
|
|
1397
|
+
display: flex;
|
|
1398
|
+
flex-direction: column;
|
|
1399
|
+
gap: 12px;
|
|
1400
|
+
}
|
|
1401
|
+
.stack-sm {
|
|
1402
|
+
display: flex;
|
|
1403
|
+
flex-direction: column;
|
|
1404
|
+
gap: 8px;
|
|
1405
|
+
}
|
|
1406
|
+
.inline {
|
|
1407
|
+
display: flex;
|
|
1408
|
+
align-items: center;
|
|
1409
|
+
gap: 8px;
|
|
1410
|
+
flex-wrap: wrap;
|
|
1411
|
+
}
|
|
1412
|
+
.between {
|
|
1413
|
+
display: flex;
|
|
1414
|
+
align-items: center;
|
|
1415
|
+
justify-content: space-between;
|
|
1416
|
+
gap: 8px;
|
|
1417
|
+
}
|
|
1418
|
+
.center {
|
|
1419
|
+
text-align: center;
|
|
1420
|
+
}
|
|
1421
|
+
.spinner {
|
|
1422
|
+
width: 16px;
|
|
1423
|
+
height: 16px;
|
|
1424
|
+
border-radius: 50%;
|
|
1425
|
+
border: 2px solid color-mix(in oklab, currentColor 30%, transparent);
|
|
1426
|
+
border-top-color: currentColor;
|
|
1427
|
+
animation: authui-spin 0.7s linear infinite;
|
|
1428
|
+
flex-shrink: 0;
|
|
1429
|
+
}
|
|
1430
|
+
@keyframes authui-spin {
|
|
1431
|
+
to {
|
|
1432
|
+
transform: rotate(360deg);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
.avatar {
|
|
1436
|
+
width: 36px;
|
|
1437
|
+
height: 36px;
|
|
1438
|
+
border-radius: 50%;
|
|
1439
|
+
background: var(--authui-muted);
|
|
1440
|
+
color: var(--authui-muted-foreground);
|
|
1441
|
+
display: inline-flex;
|
|
1442
|
+
align-items: center;
|
|
1443
|
+
justify-content: center;
|
|
1444
|
+
font-weight: 600;
|
|
1445
|
+
font-size: 14px;
|
|
1446
|
+
flex-shrink: 0;
|
|
1447
|
+
overflow: hidden;
|
|
1448
|
+
text-transform: uppercase;
|
|
1449
|
+
}
|
|
1450
|
+
.avatar img {
|
|
1451
|
+
width: 100%;
|
|
1452
|
+
height: 100%;
|
|
1453
|
+
object-fit: cover;
|
|
1454
|
+
}
|
|
1455
|
+
.logo {
|
|
1456
|
+
display: block;
|
|
1457
|
+
max-height: 40px;
|
|
1458
|
+
max-width: 160px;
|
|
1459
|
+
margin: 0 auto 16px;
|
|
1460
|
+
}
|
|
1461
|
+
.code {
|
|
1462
|
+
font-family: var(--authui-font-mono);
|
|
1463
|
+
font-size: 13px;
|
|
1464
|
+
border-radius: var(--authui-radius-md);
|
|
1465
|
+
border: 1px solid var(--authui-border);
|
|
1466
|
+
background: color-mix(in oklab, var(--authui-muted) 50%, transparent);
|
|
1467
|
+
padding: 2px 6px;
|
|
1468
|
+
color: color-mix(in oklab, var(--authui-foreground) 85%, transparent);
|
|
1469
|
+
word-break: break-all;
|
|
1470
|
+
user-select: all;
|
|
1471
|
+
}
|
|
1472
|
+
.codes {
|
|
1473
|
+
display: grid;
|
|
1474
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1475
|
+
gap: 8px;
|
|
1476
|
+
}
|
|
1477
|
+
.qr {
|
|
1478
|
+
display: block;
|
|
1479
|
+
width: 168px;
|
|
1480
|
+
height: 168px;
|
|
1481
|
+
margin: 0 auto;
|
|
1482
|
+
border-radius: var(--authui-radius-md);
|
|
1483
|
+
border: 1px solid var(--authui-border);
|
|
1484
|
+
background: #fff;
|
|
1485
|
+
padding: 8px;
|
|
1486
|
+
}
|
|
1487
|
+
.legal {
|
|
1488
|
+
font-size: 12px;
|
|
1489
|
+
color: var(--authui-muted-foreground);
|
|
1490
|
+
text-align: center;
|
|
1491
|
+
margin: 0;
|
|
1492
|
+
line-height: 1.6;
|
|
1493
|
+
}
|
|
1494
|
+
.legal a {
|
|
1495
|
+
color: inherit;
|
|
1496
|
+
text-decoration: underline;
|
|
1497
|
+
text-decoration-style: dotted;
|
|
1498
|
+
text-underline-offset: 3px;
|
|
1499
|
+
}
|
|
1500
|
+
.legal a:hover {
|
|
1501
|
+
color: var(--authui-foreground);
|
|
1502
|
+
}
|
|
1503
|
+
.links {
|
|
1504
|
+
display: flex;
|
|
1505
|
+
justify-content: center;
|
|
1506
|
+
align-items: center;
|
|
1507
|
+
gap: 12px;
|
|
1508
|
+
font-size: 13px;
|
|
1509
|
+
color: var(--authui-muted-foreground);
|
|
1510
|
+
flex-wrap: wrap;
|
|
1511
|
+
}
|
|
1512
|
+
.providers {
|
|
1513
|
+
display: grid;
|
|
1514
|
+
gap: 8px;
|
|
1515
|
+
}
|
|
1516
|
+
.providers.two {
|
|
1517
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
1518
|
+
}
|
|
1519
|
+
.providers .btn svg {
|
|
1520
|
+
width: 18px;
|
|
1521
|
+
height: 18px;
|
|
1522
|
+
}
|
|
1523
|
+
.empty {
|
|
1524
|
+
padding: 24px 0;
|
|
1525
|
+
text-align: center;
|
|
1526
|
+
font-size: 13px;
|
|
1527
|
+
color: var(--authui-muted-foreground);
|
|
1528
|
+
}
|
|
1529
|
+
.choice {
|
|
1530
|
+
display: flex;
|
|
1531
|
+
align-items: center;
|
|
1532
|
+
gap: 12px;
|
|
1533
|
+
width: 100%;
|
|
1534
|
+
padding: 12px 14px;
|
|
1535
|
+
border-radius: var(--authui-radius-lg);
|
|
1536
|
+
border: 1px solid var(--authui-border);
|
|
1537
|
+
background: transparent;
|
|
1538
|
+
color: var(--authui-foreground);
|
|
1539
|
+
font: inherit;
|
|
1540
|
+
text-align: start;
|
|
1541
|
+
cursor: pointer;
|
|
1542
|
+
transition:
|
|
1543
|
+
background-color 150ms,
|
|
1544
|
+
border-color 150ms;
|
|
1545
|
+
}
|
|
1546
|
+
.choice:hover {
|
|
1547
|
+
background: var(--authui-accent);
|
|
1548
|
+
}
|
|
1549
|
+
.choice:focus-visible {
|
|
1550
|
+
outline: none;
|
|
1551
|
+
border-color: var(--authui-ring);
|
|
1552
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--authui-ring) 50%, transparent);
|
|
1553
|
+
}
|
|
1554
|
+
.choice svg {
|
|
1555
|
+
width: 18px;
|
|
1556
|
+
height: 18px;
|
|
1557
|
+
color: var(--authui-muted-foreground);
|
|
1558
|
+
flex-shrink: 0;
|
|
1559
|
+
}
|
|
1560
|
+
.choice-title {
|
|
1561
|
+
font-weight: 500;
|
|
1562
|
+
font-size: 14px;
|
|
1563
|
+
}
|
|
1564
|
+
.choice-sub {
|
|
1565
|
+
font-size: 12px;
|
|
1566
|
+
color: var(--authui-muted-foreground);
|
|
1567
|
+
}
|
|
1568
|
+
.switch {
|
|
1569
|
+
position: relative;
|
|
1570
|
+
width: 36px;
|
|
1571
|
+
height: 20px;
|
|
1572
|
+
border-radius: 999px;
|
|
1573
|
+
border: 1px solid transparent;
|
|
1574
|
+
background: var(--authui-input);
|
|
1575
|
+
cursor: pointer;
|
|
1576
|
+
transition: background-color 150ms;
|
|
1577
|
+
flex-shrink: 0;
|
|
1578
|
+
padding: 0;
|
|
1579
|
+
}
|
|
1580
|
+
.switch[aria-checked="true"] {
|
|
1581
|
+
background: var(--authui-primary);
|
|
1582
|
+
}
|
|
1583
|
+
.switch::after {
|
|
1584
|
+
content: "";
|
|
1585
|
+
position: absolute;
|
|
1586
|
+
top: 2px;
|
|
1587
|
+
inset-inline-start: 2px;
|
|
1588
|
+
width: 14px;
|
|
1589
|
+
height: 14px;
|
|
1590
|
+
border-radius: 50%;
|
|
1591
|
+
background: var(--authui-background);
|
|
1592
|
+
transition: transform 150ms;
|
|
1593
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
1594
|
+
}
|
|
1595
|
+
.switch[aria-checked="true"]::after {
|
|
1596
|
+
transform: translateX(16px);
|
|
1597
|
+
}
|
|
1598
|
+
.switch:focus-visible {
|
|
1599
|
+
outline: none;
|
|
1600
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--authui-ring) 50%, transparent);
|
|
1601
|
+
}
|
|
1602
|
+
.switch:disabled {
|
|
1603
|
+
opacity: 0.5;
|
|
1604
|
+
cursor: not-allowed;
|
|
1605
|
+
}
|
|
1606
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1607
|
+
*,
|
|
1608
|
+
*::before,
|
|
1609
|
+
*::after {
|
|
1610
|
+
transition: none !important;
|
|
1611
|
+
animation-duration: 0.01ms !important;
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
`;
|
|
1615
|
+
var ct = Object.defineProperty, lt = (e, t, i, r) => {
|
|
1616
|
+
for (var a = void 0, u = e.length - 1, h; u >= 0; u--)
|
|
1617
|
+
(h = e[u]) && (a = h(t, i, a) || a);
|
|
1618
|
+
return a && ct(t, i, a), a;
|
|
1619
|
+
};
|
|
1620
|
+
const H = class H extends V {
|
|
1621
|
+
constructor() {
|
|
1622
|
+
super(...arguments), this.auth = o.getState(), this.unsubscribeStore = null, this.unsubscribeTheme = null;
|
|
1623
|
+
}
|
|
1624
|
+
connectedCallback() {
|
|
1625
|
+
super.connectedCallback(), this.auth = o.getState(), this.unsubscribeStore = o.on("change", (t) => {
|
|
1626
|
+
this.auth = t, this.applyBranding();
|
|
1627
|
+
}), this.unsubscribeTheme = W.subscribe(() => this.applyBranding()), this.applyBranding();
|
|
1628
|
+
}
|
|
1629
|
+
disconnectedCallback() {
|
|
1630
|
+
super.disconnectedCallback(), this.unsubscribeStore?.(), this.unsubscribeTheme?.(), this.unsubscribeStore = null, this.unsubscribeTheme = null;
|
|
1631
|
+
}
|
|
1632
|
+
get strings() {
|
|
1633
|
+
return o.getStrings();
|
|
1634
|
+
}
|
|
1635
|
+
/** Translate a string key with optional `{placeholders}`. */
|
|
1636
|
+
t(t, i) {
|
|
1637
|
+
return it(this.strings[t], i);
|
|
1638
|
+
}
|
|
1639
|
+
get config() {
|
|
1640
|
+
return o.getConfig();
|
|
1641
|
+
}
|
|
1642
|
+
get productName() {
|
|
1643
|
+
return this.config?.branding?.name ?? "";
|
|
1644
|
+
}
|
|
1645
|
+
/** Push theme and branding from config onto the host element. */
|
|
1646
|
+
applyBranding() {
|
|
1647
|
+
const t = this.config?.branding, i = W.isDark(t?.theme ?? "auto");
|
|
1648
|
+
this.setAttribute("data-theme", i ? "dark" : "light"), t?.primary && (this.style.setProperty("--authui-primary", t.primary), this.style.setProperty(
|
|
1649
|
+
"--authui-primary-foreground",
|
|
1650
|
+
t.primaryForeground ?? "#ffffff"
|
|
1651
|
+
)), t?.radius && G[t.radius] && this.style.setProperty("--authui-radius", G[t.radius]);
|
|
1652
|
+
}
|
|
1653
|
+
/** Emit a composed custom event from this element. */
|
|
1654
|
+
fire(t, i) {
|
|
1655
|
+
this.dispatchEvent(new CustomEvent(t, { detail: i, bubbles: !0, composed: !0 }));
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
H.styles = [ot, nt];
|
|
1659
|
+
let x = H;
|
|
1660
|
+
lt([
|
|
1661
|
+
d()
|
|
1662
|
+
], x.prototype, "auth");
|
|
1663
|
+
var dt = Object.defineProperty, ut = Object.getOwnPropertyDescriptor, w = (e, t, i, r) => {
|
|
1664
|
+
for (var a = r > 1 ? void 0 : r ? ut(t, i) : t, u = e.length - 1, h; u >= 0; u--)
|
|
1665
|
+
(h = e[u]) && (a = (r ? h(t, i, a) : h(a)) || a);
|
|
1666
|
+
return r && a && dt(t, i, a), a;
|
|
1667
|
+
};
|
|
1668
|
+
let v = class extends V {
|
|
1669
|
+
constructor() {
|
|
1670
|
+
super(...arguments), this.endpoint = "", this.project = "", this.redirectUrl = "", this.successUrl = "", this.methods = "email-password", this.signUp = "true", this.requireName = "true", this.mfa = "true", this.securityPhrase = "true", this.name = "", this.logo = "", this.theme = "auto", this.radius = "", this.primary = "", this.primaryForeground = "", this.termsUrl = "", this.privacyUrl = "";
|
|
1671
|
+
}
|
|
1672
|
+
connectedCallback() {
|
|
1673
|
+
super.connectedCallback(), this.configure();
|
|
1674
|
+
}
|
|
1675
|
+
updated() {
|
|
1676
|
+
this.configure();
|
|
1677
|
+
}
|
|
1678
|
+
configure() {
|
|
1679
|
+
if (!this.endpoint || !this.project) return;
|
|
1680
|
+
const e = this.toConfig(), t = o.getConfig();
|
|
1681
|
+
t && JSON.stringify(t) === JSON.stringify(e) || o.configure(e);
|
|
1682
|
+
}
|
|
1683
|
+
toConfig() {
|
|
1684
|
+
const e = { oauth: [] };
|
|
1685
|
+
for (const t of this.methods.split(/[\s,]+/).filter(Boolean))
|
|
1686
|
+
t.startsWith("oauth:") ? e.oauth.push(t.slice(6)) : t === "email-password" ? e.emailPassword = !0 : t === "magic-url" ? e.magicUrl = !0 : t === "email-otp" ? e.emailOtp = !0 : t === "phone" ? e.phone = !0 : (t === "anonymous" || t === "guest") && (e.anonymous = !0);
|
|
1687
|
+
return e.emailPassword === void 0 && !this.methods.trim() && (e.emailPassword = !0), {
|
|
1688
|
+
endpoint: this.endpoint,
|
|
1689
|
+
project: this.project,
|
|
1690
|
+
redirectUrl: this.redirectUrl || void 0,
|
|
1691
|
+
successUrl: this.successUrl || void 0,
|
|
1692
|
+
methods: e,
|
|
1693
|
+
signUp: this.signUp !== "false",
|
|
1694
|
+
requireName: this.requireName !== "false",
|
|
1695
|
+
mfa: this.mfa !== "false",
|
|
1696
|
+
securityPhrase: this.securityPhrase !== "false",
|
|
1697
|
+
branding: {
|
|
1698
|
+
name: this.name || void 0,
|
|
1699
|
+
logo: this.logo || void 0,
|
|
1700
|
+
theme: this.theme || "auto",
|
|
1701
|
+
radius: this.radius || void 0,
|
|
1702
|
+
primary: this.primary || void 0,
|
|
1703
|
+
primaryForeground: this.primaryForeground || void 0
|
|
1704
|
+
},
|
|
1705
|
+
legal: {
|
|
1706
|
+
termsUrl: this.termsUrl || void 0,
|
|
1707
|
+
privacyUrl: this.privacyUrl || void 0
|
|
1708
|
+
}
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1711
|
+
};
|
|
1712
|
+
v.styles = A`
|
|
1713
|
+
:host {
|
|
1714
|
+
display: none;
|
|
1715
|
+
}
|
|
1716
|
+
`;
|
|
1717
|
+
w([
|
|
1718
|
+
g({ type: String })
|
|
1719
|
+
], v.prototype, "endpoint", 2);
|
|
1720
|
+
w([
|
|
1721
|
+
g({ type: String })
|
|
1722
|
+
], v.prototype, "project", 2);
|
|
1723
|
+
w([
|
|
1724
|
+
g({ type: String, attribute: "redirect-url" })
|
|
1725
|
+
], v.prototype, "redirectUrl", 2);
|
|
1726
|
+
w([
|
|
1727
|
+
g({ type: String, attribute: "success-url" })
|
|
1728
|
+
], v.prototype, "successUrl", 2);
|
|
1729
|
+
w([
|
|
1730
|
+
g({ type: String })
|
|
1731
|
+
], v.prototype, "methods", 2);
|
|
1732
|
+
w([
|
|
1733
|
+
g({ type: String, attribute: "sign-up" })
|
|
1734
|
+
], v.prototype, "signUp", 2);
|
|
1735
|
+
w([
|
|
1736
|
+
g({ type: String, attribute: "require-name" })
|
|
1737
|
+
], v.prototype, "requireName", 2);
|
|
1738
|
+
w([
|
|
1739
|
+
g({ type: String })
|
|
1740
|
+
], v.prototype, "mfa", 2);
|
|
1741
|
+
w([
|
|
1742
|
+
g({ type: String, attribute: "security-phrase" })
|
|
1743
|
+
], v.prototype, "securityPhrase", 2);
|
|
1744
|
+
w([
|
|
1745
|
+
g({ type: String })
|
|
1746
|
+
], v.prototype, "name", 2);
|
|
1747
|
+
w([
|
|
1748
|
+
g({ type: String })
|
|
1749
|
+
], v.prototype, "logo", 2);
|
|
1750
|
+
w([
|
|
1751
|
+
g({ type: String })
|
|
1752
|
+
], v.prototype, "theme", 2);
|
|
1753
|
+
w([
|
|
1754
|
+
g({ type: String })
|
|
1755
|
+
], v.prototype, "radius", 2);
|
|
1756
|
+
w([
|
|
1757
|
+
g({ type: String })
|
|
1758
|
+
], v.prototype, "primary", 2);
|
|
1759
|
+
w([
|
|
1760
|
+
g({ type: String, attribute: "primary-foreground" })
|
|
1761
|
+
], v.prototype, "primaryForeground", 2);
|
|
1762
|
+
w([
|
|
1763
|
+
g({ type: String, attribute: "terms-url" })
|
|
1764
|
+
], v.prototype, "termsUrl", 2);
|
|
1765
|
+
w([
|
|
1766
|
+
g({ type: String, attribute: "privacy-url" })
|
|
1767
|
+
], v.prototype, "privacyUrl", 2);
|
|
1768
|
+
v = w([
|
|
1769
|
+
S("authui-config")
|
|
1770
|
+
], v);
|
|
1771
|
+
var ht = Object.defineProperty, pt = Object.getOwnPropertyDescriptor, B = (e, t, i, r) => {
|
|
1772
|
+
for (var a = r > 1 ? void 0 : r ? pt(t, i) : t, u = e.length - 1, h; u >= 0; u--)
|
|
1773
|
+
(h = e[u]) && (a = (r ? h(t, i, a) : h(a)) || a);
|
|
1774
|
+
return r && a && ht(t, i, a), a;
|
|
1775
|
+
};
|
|
1776
|
+
if (typeof document < "u" && !document.getElementById("authui-fouc")) {
|
|
1777
|
+
const e = document.createElement("style");
|
|
1778
|
+
e.id = "authui-fouc", e.textContent = "authui-signed-in:not([ready]),authui-signed-out:not([ready]){display:none}", document.head.appendChild(e);
|
|
1779
|
+
}
|
|
1780
|
+
class T extends V {
|
|
1781
|
+
constructor() {
|
|
1782
|
+
super(...arguments), this.show = !1, this.unsubscribe = null;
|
|
1783
|
+
}
|
|
1784
|
+
connectedCallback() {
|
|
1785
|
+
super.connectedCallback(), this.evaluate(o.getState().status), this.unsubscribe = o.on("change", (t) => this.evaluate(t.status));
|
|
1786
|
+
}
|
|
1787
|
+
disconnectedCallback() {
|
|
1788
|
+
super.disconnectedCallback(), this.unsubscribe?.();
|
|
1789
|
+
}
|
|
1790
|
+
evaluate(t) {
|
|
1791
|
+
t !== "loading" && (this.show = this.shouldShow(t), this.setAttribute("ready", ""), this.style.display = "contents");
|
|
1792
|
+
}
|
|
1793
|
+
render() {
|
|
1794
|
+
return this.show ? s`<slot></slot>` : n;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
B([
|
|
1798
|
+
d()
|
|
1799
|
+
], T.prototype, "show", 2);
|
|
1800
|
+
let Y = class extends T {
|
|
1801
|
+
shouldShow(e) {
|
|
1802
|
+
return e === "signed-in";
|
|
1803
|
+
}
|
|
1804
|
+
};
|
|
1805
|
+
Y = B([
|
|
1806
|
+
S("authui-signed-in")
|
|
1807
|
+
], Y);
|
|
1808
|
+
let K = class extends T {
|
|
1809
|
+
shouldShow(e) {
|
|
1810
|
+
return e !== "signed-in";
|
|
1811
|
+
}
|
|
1812
|
+
};
|
|
1813
|
+
K = B([
|
|
1814
|
+
S("authui-signed-out")
|
|
1815
|
+
], K);
|
|
1816
|
+
const ft = A`
|
|
1817
|
+
:host {
|
|
1818
|
+
display: block;
|
|
1819
|
+
width: 100%;
|
|
1820
|
+
max-width: 420px;
|
|
1821
|
+
}
|
|
1822
|
+
.panel {
|
|
1823
|
+
background: var(--authui-card);
|
|
1824
|
+
color: var(--authui-card-foreground);
|
|
1825
|
+
border: 1px solid var(--authui-border);
|
|
1826
|
+
border-radius: var(--authui-radius-xl);
|
|
1827
|
+
padding: 24px;
|
|
1828
|
+
display: flex;
|
|
1829
|
+
flex-direction: column;
|
|
1830
|
+
gap: 20px;
|
|
1831
|
+
box-shadow: var(--authui-shadow-lg);
|
|
1832
|
+
}
|
|
1833
|
+
.panel.embedded {
|
|
1834
|
+
border: 0;
|
|
1835
|
+
box-shadow: none;
|
|
1836
|
+
padding: 0;
|
|
1837
|
+
background: transparent;
|
|
1838
|
+
}
|
|
1839
|
+
.header {
|
|
1840
|
+
text-align: center;
|
|
1841
|
+
display: flex;
|
|
1842
|
+
flex-direction: column;
|
|
1843
|
+
gap: 4px;
|
|
1844
|
+
}
|
|
1845
|
+
.header:empty {
|
|
1846
|
+
display: none;
|
|
1847
|
+
}
|
|
1848
|
+
.alert .dismiss {
|
|
1849
|
+
position: absolute;
|
|
1850
|
+
top: 4px;
|
|
1851
|
+
inset-inline-end: 4px;
|
|
1852
|
+
width: 28px;
|
|
1853
|
+
height: 28px;
|
|
1854
|
+
}
|
|
1855
|
+
.alert .dismiss svg {
|
|
1856
|
+
width: 14px;
|
|
1857
|
+
height: 14px;
|
|
1858
|
+
margin: 0;
|
|
1859
|
+
}
|
|
1860
|
+
`, f = (e) => s`<svg
|
|
1861
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1862
|
+
viewBox="0 0 24 24"
|
|
1863
|
+
fill="none"
|
|
1864
|
+
stroke="currentColor"
|
|
1865
|
+
stroke-width="2"
|
|
1866
|
+
stroke-linecap="round"
|
|
1867
|
+
stroke-linejoin="round"
|
|
1868
|
+
aria-hidden="true"
|
|
1869
|
+
>
|
|
1870
|
+
${e}
|
|
1871
|
+
</svg>`, c = {
|
|
1872
|
+
mail: f(
|
|
1873
|
+
l`<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>`
|
|
1874
|
+
),
|
|
1875
|
+
phone: f(
|
|
1876
|
+
l`<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>`
|
|
1877
|
+
),
|
|
1878
|
+
user: f(
|
|
1879
|
+
l`<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>`
|
|
1880
|
+
),
|
|
1881
|
+
userX: f(
|
|
1882
|
+
l`<path d="M2 21a8 8 0 0 1 11.873-7"/><circle cx="10" cy="8" r="5"/><path d="m17 17 5 5"/><path d="m22 17-5 5"/>`
|
|
1883
|
+
),
|
|
1884
|
+
lock: f(
|
|
1885
|
+
l`<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>`
|
|
1886
|
+
),
|
|
1887
|
+
key: f(
|
|
1888
|
+
l`<path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4"/><path d="m21 2-9.6 9.6"/><circle cx="7.5" cy="15.5" r="5.5"/>`
|
|
1889
|
+
),
|
|
1890
|
+
shield: f(
|
|
1891
|
+
l`<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>`
|
|
1892
|
+
),
|
|
1893
|
+
shieldCheck: f(
|
|
1894
|
+
l`<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/>`
|
|
1895
|
+
),
|
|
1896
|
+
smartphone: f(
|
|
1897
|
+
l`<rect width="14" height="20" x="5" y="2" rx="2" ry="2"/><path d="M12 18h.01"/>`
|
|
1898
|
+
),
|
|
1899
|
+
monitor: f(
|
|
1900
|
+
l`<rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>`
|
|
1901
|
+
),
|
|
1902
|
+
globe: f(
|
|
1903
|
+
l`<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>`
|
|
1904
|
+
),
|
|
1905
|
+
logOut: f(
|
|
1906
|
+
l`<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/>`
|
|
1907
|
+
),
|
|
1908
|
+
settings: f(
|
|
1909
|
+
l`<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/>`
|
|
1910
|
+
),
|
|
1911
|
+
x: f(l`<path d="M18 6 6 18"/><path d="m6 6 12 12"/>`),
|
|
1912
|
+
check: f(l`<path d="M20 6 9 17l-5-5"/>`),
|
|
1913
|
+
copy: f(
|
|
1914
|
+
l`<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>`
|
|
1915
|
+
),
|
|
1916
|
+
eye: f(
|
|
1917
|
+
l`<path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/>`
|
|
1918
|
+
),
|
|
1919
|
+
eyeOff: f(
|
|
1920
|
+
l`<path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"/><path d="m2 2 20 20"/>`
|
|
1921
|
+
),
|
|
1922
|
+
arrowLeft: f(l`<path d="m12 19-7-7 7-7"/><path d="M19 12H5"/>`),
|
|
1923
|
+
alert: f(
|
|
1924
|
+
l`<circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/>`
|
|
1925
|
+
),
|
|
1926
|
+
info: f(l`<circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/>`),
|
|
1927
|
+
checkCircle: f(l`<circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/>`),
|
|
1928
|
+
link: f(
|
|
1929
|
+
l`<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>`
|
|
1930
|
+
),
|
|
1931
|
+
activity: f(
|
|
1932
|
+
l`<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"/>`
|
|
1933
|
+
),
|
|
1934
|
+
trash: f(
|
|
1935
|
+
l`<path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>`
|
|
1936
|
+
),
|
|
1937
|
+
sparkles: f(
|
|
1938
|
+
l`<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>`
|
|
1939
|
+
),
|
|
1940
|
+
refresh: f(
|
|
1941
|
+
l`<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/>`
|
|
1942
|
+
),
|
|
1943
|
+
chevronDown: f(l`<path d="m6 9 6 6 6-6"/>`),
|
|
1944
|
+
ghost: f(
|
|
1945
|
+
l`<path d="M9 10h.01"/><path d="M15 10h.01"/><path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z"/>`
|
|
1946
|
+
),
|
|
1947
|
+
qr: f(
|
|
1948
|
+
l`<rect width="5" height="5" x="3" y="3" rx="1"/><rect width="5" height="5" x="16" y="3" rx="1"/><rect width="5" height="5" x="3" y="16" rx="1"/><path d="M21 16h-3a2 2 0 0 0-2 2v3"/><path d="M21 21v.01"/><path d="M12 7v3a2 2 0 0 1-2 2H7"/><path d="M3 12h.01"/><path d="M12 3h.01"/><path d="M12 16v.01"/><path d="M16 12h1"/><path d="M21 12v.01"/><path d="M12 21v-1"/>`
|
|
1949
|
+
)
|
|
1950
|
+
}, y = (e, t = "0 0 24 24") => s`<svg xmlns="http://www.w3.org/2000/svg" viewBox=${t} aria-hidden="true">${e}</svg>`, mt = {
|
|
1951
|
+
google: y(
|
|
1952
|
+
l`<path fill="#4285F4" d="M23.49 12.27c0-.79-.07-1.54-.19-2.27H12v4.51h6.47a5.57 5.57 0 0 1-2.4 3.58v3h3.86c2.26-2.09 3.56-5.17 3.56-8.82z"/><path fill="#34A853" d="M12 24c3.24 0 5.95-1.08 7.93-2.91l-3.86-3c-1.08.72-2.45 1.16-4.07 1.16-3.13 0-5.78-2.11-6.73-4.96H1.29v3.09A11.99 11.99 0 0 0 12 24z"/><path fill="#FBBC05" d="M5.27 14.29A7.2 7.2 0 0 1 4.89 12c0-.8.14-1.57.38-2.29V6.62H1.29A11.97 11.97 0 0 0 0 12c0 1.94.46 3.77 1.29 5.38l3.98-3.09z"/><path fill="#EA4335" d="M12 4.75c1.77 0 3.35.61 4.6 1.8l3.42-3.42C17.95 1.19 15.24 0 12 0 7.31 0 3.26 2.69 1.29 6.62l3.98 3.09C6.22 6.86 8.87 4.75 12 4.75z"/>`
|
|
1953
|
+
),
|
|
1954
|
+
github: y(
|
|
1955
|
+
l`<path fill="currentColor" d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"/>`
|
|
1956
|
+
),
|
|
1957
|
+
apple: y(
|
|
1958
|
+
l`<path fill="currentColor" d="M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/>`
|
|
1959
|
+
),
|
|
1960
|
+
facebook: y(
|
|
1961
|
+
l`<path fill="#1877F2" d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>`
|
|
1962
|
+
),
|
|
1963
|
+
x: y(
|
|
1964
|
+
l`<path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>`
|
|
1965
|
+
),
|
|
1966
|
+
microsoft: y(
|
|
1967
|
+
l`<path fill="#F25022" d="M1 1h10v10H1z"/><path fill="#7FBA00" d="M13 1h10v10H13z"/><path fill="#00A4EF" d="M1 13h10v10H1z"/><path fill="#FFB900" d="M13 13h10v10H13z"/>`
|
|
1968
|
+
),
|
|
1969
|
+
discord: y(
|
|
1970
|
+
l`<path fill="#5865F2" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>`
|
|
1971
|
+
),
|
|
1972
|
+
gitlab: y(
|
|
1973
|
+
l`<path fill="#FC6D26" d="m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.876.876 0 0 0-1.001.054.874.874 0 0 0-.29.44l-2.205 6.748H7.535L5.33 1.069a.857.857 0 0 0-.29-.441.876.876 0 0 0-1.001-.054.86.86 0 0 0-.336.405L.436 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.011.009.03.021 4.976 3.727 2.462 1.863 1.5 1.132a1.009 1.009 0 0 0 1.22 0l1.5-1.132 2.461-1.863 5.006-3.75.013-.01a6.068 6.068 0 0 0 2.006-7.002z"/>`
|
|
1974
|
+
),
|
|
1975
|
+
linkedin: y(
|
|
1976
|
+
l`<path fill="#0A66C2" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>`
|
|
1977
|
+
),
|
|
1978
|
+
slack: y(
|
|
1979
|
+
l`<path fill="#E01E5A" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313z"/><path fill="#36C5F0" d="M8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312z"/><path fill="#2EB67D" d="M18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.27 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.163 0a2.528 2.528 0 0 1 2.523 2.522v6.312z"/><path fill="#ECB22E" d="M15.163 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.163 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.27a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.315A2.527 2.527 0 0 1 24 15.163a2.528 2.528 0 0 1-2.522 2.523h-6.315z"/>`
|
|
1980
|
+
),
|
|
1981
|
+
twitch: y(
|
|
1982
|
+
l`<path fill="#9146FF" d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0 1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/>`
|
|
1983
|
+
),
|
|
1984
|
+
spotify: y(
|
|
1985
|
+
l`<path fill="#1DB954" d="M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z"/>`
|
|
1986
|
+
),
|
|
1987
|
+
notion: y(
|
|
1988
|
+
l`<path fill="currentColor" d="M4.459 4.208c.746.606 1.026.56 2.428.466l13.215-.793c.28 0 .047-.28-.046-.326L17.86 1.968c-.42-.326-.981-.7-2.055-.607L3.01 2.295c-.466.046-.56.28-.374.466zm.793 3.08v13.904c0 .747.373 1.027 1.214.98l14.523-.84c.841-.046.935-.56.935-1.167V6.354c0-.606-.233-.933-.748-.887l-15.177.887c-.56.047-.747.327-.747.933zm14.337.745c.093.42 0 .84-.42.888l-.7.14v10.264c-.608.327-1.168.514-1.635.514-.748 0-.935-.234-1.495-.933l-4.577-7.186v6.952L12.21 19s0 .84-1.168.84l-3.222.186c-.093-.186 0-.653.327-.746l.84-.233V9.854L7.822 9.76c-.094-.42.14-1.026.793-1.073l3.456-.233 4.764 7.279v-6.44l-1.215-.139c-.093-.514.28-.887.747-.933zM1.936 1.035l13.31-.98c1.634-.14 2.055-.047 3.082.7l4.249 2.986c.7.513.934.653.934 1.213v16.378c0 1.026-.373 1.634-1.68 1.726l-15.458.934c-.98.047-1.448-.093-1.962-.747l-3.129-4.06c-.56-.747-.793-1.306-.793-1.96V2.667c0-.839.374-1.54 1.447-1.632z"/>`
|
|
1989
|
+
),
|
|
1990
|
+
dropbox: y(
|
|
1991
|
+
l`<path fill="#0061FF" d="M6 1.807 0 5.629l6 3.822 6.001-3.822L6 1.807zm12 0-6 3.822 6 3.822 6-3.822-6-3.822zM0 13.274l6 3.822 6.001-3.822L6 9.452l-6 3.822zm18-3.822-6 3.822 6 3.822 6-3.822-6-3.822zM6 18.371l6.001 3.822 6-3.822-6-3.822L6 18.371z"/>`
|
|
1992
|
+
),
|
|
1993
|
+
figma: y(
|
|
1994
|
+
l`<path fill="#F24E1E" d="M8 24a4 4 0 0 0 4-4v-4H8a4 4 0 0 0 0 8z"/><path fill="#A259FF" d="M4 12a4 4 0 0 1 4-4h4v8H8a4 4 0 0 1-4-4z"/><path fill="#FF7262" d="M4 4a4 4 0 0 1 4-4h4v8H8a4 4 0 0 1-4-4z"/><path fill="#1ABCFE" d="M12 0h4a4 4 0 0 1 0 8h-4V0z"/><path fill="#0ACF83" d="M20 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0z"/>`
|
|
1995
|
+
),
|
|
1996
|
+
bitbucket: y(
|
|
1997
|
+
l`<path fill="#2684FF" d="M.778 1.213a.768.768 0 0 0-.768.892l3.263 19.81c.084.5.515.868 1.022.873H19.95a.772.772 0 0 0 .77-.646l3.27-20.03a.768.768 0 0 0-.768-.891zM14.52 15.53H9.522L8.17 8.466h7.561z"/>`
|
|
1998
|
+
),
|
|
1999
|
+
amazon: y(
|
|
2000
|
+
l`<path fill="currentColor" d="M.045 18.02c.072-.116.187-.124.348-.022 3.636 2.11 7.594 3.166 11.87 3.166 2.852 0 5.668-.533 8.447-1.595l.315-.14c.138-.06.234-.1.293-.13.226-.088.39-.046.525.13.12.174.09.336-.12.48-.256.19-.6.41-1.006.654-1.244.743-2.64 1.316-4.185 1.726a17.617 17.617 0 0 1-10.951-.577 17.88 17.88 0 0 1-5.43-3.35c-.1-.074-.151-.15-.151-.22 0-.047.021-.09.051-.13zm6.565-6.218c0-1.005.247-1.863.743-2.577.495-.71 1.17-1.25 2.04-1.615.796-.335 1.756-.575 2.912-.72.39-.046 1.033-.103 1.92-.174v-.37c0-.93-.105-1.558-.3-1.875-.302-.43-.78-.65-1.44-.65h-.182c-.48.046-.896.196-1.246.46-.35.27-.575.63-.675 1.096-.06.3-.206.465-.435.51l-2.52-.315c-.248-.06-.372-.18-.372-.39 0-.046.007-.09.022-.15.247-1.29.855-2.25 1.82-2.88.976-.616 2.1-.975 3.39-1.05h.54c1.65 0 2.957.434 3.888 1.29.135.15.27.3.405.48.12.165.224.314.283.45.075.134.15.33.195.57.06.254.105.42.135.51.03.104.062.3.076.615.01.313.02.493.02.553v5.28c0 .376.06.72.165 1.036.105.313.21.54.315.674l.51.674c.09.136.136.256.136.36 0 .12-.06.226-.18.314-1.2 1.05-1.86 1.62-1.963 1.71-.165.135-.373.15-.61.045a6.62 6.62 0 0 1-.526-.496l-.31-.347a9.858 9.858 0 0 1-.317-.42l-.3-.435c-.81.886-1.603 1.44-2.4 1.665-.494.15-1.093.227-1.83.227-1.11 0-2.04-.343-2.76-1.034-.72-.69-1.08-1.665-1.08-2.94l-.05-.076zm3.753-.438c0 .566.14 1.02.425 1.364.285.34.675.512 1.155.512.045 0 .106-.007.195-.02.09-.016.134-.023.166-.023.614-.16 1.08-.553 1.424-1.178.165-.28.285-.58.36-.91.09-.32.12-.59.135-.8.015-.195.015-.54.015-1.005v-.54c-.84 0-1.484.06-1.92.18-1.275.36-1.92 1.17-1.92 2.43l-.035-.01zm9.162 7.027c.03-.06.075-.11.132-.17.362-.243.714-.41 1.05-.5a8.094 8.094 0 0 1 1.612-.24c.14-.012.28 0 .41.03.65.06 1.05.168 1.172.33.063.09.099.228.099.39v.15c0 .51-.149 1.11-.424 1.8-.278.69-.664 1.248-1.156 1.68-.073.06-.14.09-.197.09-.03 0-.06 0-.09-.012-.09-.044-.107-.12-.064-.24.54-1.26.806-2.143.806-2.64 0-.15-.03-.27-.087-.344-.145-.166-.55-.257-1.224-.257-.243 0-.533.016-.87.045-.363.045-.7.09-1 .135-.09 0-.148-.014-.18-.044-.03-.03-.036-.06-.02-.106 0-.014.007-.03.02-.06z"/>`
|
|
2001
|
+
),
|
|
2002
|
+
paypal: y(
|
|
2003
|
+
l`<path fill="#003087" d="M7.076 21.337H2.47a.641.641 0 0 1-.633-.74L4.944.901C5.026.382 5.474 0 5.998 0h7.46c2.57 0 4.578.543 5.69 1.81 1.01 1.15 1.304 2.42 1.012 4.287-.023.143-.047.288-.077.437-.983 5.05-4.349 6.797-8.647 6.797h-2.19c-.524 0-.968.382-1.05.9l-1.12 7.106zm14.146-14.42a3.35 3.35 0 0 0-.607-.541c-.013.076-.026.175-.041.254-.93 4.778-4.005 7.201-9.138 7.201h-2.19a.563.563 0 0 0-.556.479l-1.187 7.527h-.506l-.24 1.516a.56.56 0 0 0 .554.647h3.882c.46 0 .85-.334.922-.788.06-.26.76-4.852.816-5.09a.932.932 0 0 1 .923-.788h.58c3.76 0 6.705-1.528 7.565-5.946.36-1.847.174-3.388-.777-4.471z"/>`
|
|
2004
|
+
)
|
|
2005
|
+
};
|
|
2006
|
+
function L(e) {
|
|
2007
|
+
return mt[e] ?? c.globe;
|
|
2008
|
+
}
|
|
2009
|
+
var gt = Object.defineProperty, bt = Object.getOwnPropertyDescriptor, C = (e, t, i, r) => {
|
|
2010
|
+
for (var a = r > 1 ? void 0 : r ? bt(t, i) : t, u = e.length - 1, h; u >= 0; u--)
|
|
2011
|
+
(h = e[u]) && (a = (r ? h(t, i, a) : h(a)) || a);
|
|
2012
|
+
return r && a && gt(t, i, a), a;
|
|
2013
|
+
};
|
|
2014
|
+
let $ = class extends x {
|
|
2015
|
+
constructor() {
|
|
2016
|
+
super(...arguments), this.view = "sign-in", this.embedded = !1, this.step = "sign-in", this.busy = !1, this.error = "", this.notice = null, this.showPassword = !1, this.token = null, this.challenge = null, this.recovery = null, this.email = "", this.password = "", this.passwordConfirm = "", this.name = "", this.phone = "", this.code = "", this.onSignIn = (e) => {
|
|
2017
|
+
e.preventDefault(), this.run(async () => {
|
|
2018
|
+
await o.signInWithEmailPassword(this.email, this.password), this.password = "", this.fire("authui-success", { method: "email-password" });
|
|
2019
|
+
});
|
|
2020
|
+
}, this.onSignUp = (e) => {
|
|
2021
|
+
e.preventDefault(), this.run(async () => {
|
|
2022
|
+
await o.signUp(this.email, this.password, this.name), this.password = "", this.fire("authui-success", { method: "sign-up" });
|
|
2023
|
+
});
|
|
2024
|
+
}, this.onGuest = () => {
|
|
2025
|
+
this.run(async () => {
|
|
2026
|
+
await o.signInAnonymously(), this.fire("authui-success", { method: "anonymous" });
|
|
2027
|
+
});
|
|
2028
|
+
}, this.onOAuth = (e) => {
|
|
2029
|
+
this.run(async () => {
|
|
2030
|
+
o.signInWithOAuth(e), await new Promise((t) => setTimeout(t, 4e3));
|
|
2031
|
+
});
|
|
2032
|
+
}, this.onForgot = (e) => {
|
|
2033
|
+
e.preventDefault(), this.run(async () => {
|
|
2034
|
+
await o.sendPasswordRecovery(this.email), this.notice = { tone: "success", message: this.t("resetLinkSent", { email: this.email }) };
|
|
2035
|
+
});
|
|
2036
|
+
}, this.onReset = (e) => {
|
|
2037
|
+
if (e.preventDefault(), this.password !== this.passwordConfirm) {
|
|
2038
|
+
this.error = this.t("errorPasswordMismatch");
|
|
2039
|
+
return;
|
|
2040
|
+
}
|
|
2041
|
+
const t = this.recovery;
|
|
2042
|
+
t && this.run(async () => {
|
|
2043
|
+
await o.completePasswordRecovery(t.userId, t.secret, this.password), this.password = "", this.passwordConfirm = "", this.recovery = null, this.notice = { tone: "success", message: this.t("passwordUpdated") }, this.go("sign-in");
|
|
2044
|
+
});
|
|
2045
|
+
}, this.onMagicUrl = (e) => {
|
|
2046
|
+
e.preventDefault(), this.run(async () => {
|
|
2047
|
+
const t = await o.sendMagicUrl(this.email);
|
|
2048
|
+
this.token = {
|
|
2049
|
+
userId: t.userId,
|
|
2050
|
+
kind: "magic-url",
|
|
2051
|
+
target: this.email,
|
|
2052
|
+
phrase: t.phrase
|
|
2053
|
+
};
|
|
2054
|
+
});
|
|
2055
|
+
}, this.onEmailOtp = (e) => {
|
|
2056
|
+
e.preventDefault(), this.run(async () => {
|
|
2057
|
+
const t = await o.sendEmailOtp(this.email);
|
|
2058
|
+
this.token = {
|
|
2059
|
+
userId: t.userId,
|
|
2060
|
+
kind: "email-otp",
|
|
2061
|
+
target: this.email,
|
|
2062
|
+
phrase: t.phrase
|
|
2063
|
+
}, this.code = "";
|
|
2064
|
+
});
|
|
2065
|
+
}, this.onPhoneOtp = (e) => {
|
|
2066
|
+
e.preventDefault(), this.run(async () => {
|
|
2067
|
+
const t = await o.sendPhoneOtp(this.phone);
|
|
2068
|
+
this.token = { userId: t.userId, kind: "phone", target: this.phone }, this.code = "";
|
|
2069
|
+
});
|
|
2070
|
+
}, this.onVerifyCode = (e) => {
|
|
2071
|
+
e.preventDefault();
|
|
2072
|
+
const t = this.token;
|
|
2073
|
+
t && this.run(async () => {
|
|
2074
|
+
await o.signInWithToken(t.userId, this.code), this.code = "", this.fire("authui-success", { method: t.kind });
|
|
2075
|
+
}, "code");
|
|
2076
|
+
}, this.onChooseFactor = (e) => {
|
|
2077
|
+
this.run(async () => {
|
|
2078
|
+
const t = await o.createMfaChallenge(e);
|
|
2079
|
+
this.challenge = { id: t.$id, factor: e }, this.code = "";
|
|
2080
|
+
});
|
|
2081
|
+
}, this.onVerifyFactor = (e) => {
|
|
2082
|
+
e.preventDefault();
|
|
2083
|
+
const t = this.challenge;
|
|
2084
|
+
t && this.run(async () => {
|
|
2085
|
+
await o.completeMfaChallenge(t.id, this.code), this.code = "", this.challenge = null, this.fire("authui-success", { method: "mfa" });
|
|
2086
|
+
}, "code");
|
|
2087
|
+
}, this.onCancelMfa = () => {
|
|
2088
|
+
this.run(async () => {
|
|
2089
|
+
try {
|
|
2090
|
+
await o.signOut();
|
|
2091
|
+
} catch (e) {
|
|
2092
|
+
if (!F(e, b.sessionNotFound)) throw e;
|
|
2093
|
+
}
|
|
2094
|
+
this.go("sign-in");
|
|
2095
|
+
});
|
|
2096
|
+
}, this.onSignOut = () => {
|
|
2097
|
+
this.run(() => o.signOut());
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
connectedCallback() {
|
|
2101
|
+
super.connectedCallback(), this.step = this.view, this.syncFromStore();
|
|
2102
|
+
}
|
|
2103
|
+
willUpdate(e) {
|
|
2104
|
+
e.has("view") && e.get("view") !== void 0 && this.go(this.view), e.has("auth") && this.syncFromStore();
|
|
2105
|
+
}
|
|
2106
|
+
updated(e) {
|
|
2107
|
+
e.has("step") && requestAnimationFrame(() => this.firstInput?.focus());
|
|
2108
|
+
}
|
|
2109
|
+
/** React to store transitions: MFA pending, redirect results, sign in. */
|
|
2110
|
+
syncFromStore() {
|
|
2111
|
+
const { status: e, pending: t } = this.auth;
|
|
2112
|
+
e === "mfa-required" && this.step !== "mfa" && this.go("mfa"), t?.type === "reset-password" && this.step !== "reset-password" && (this.recovery = { userId: t.userId, secret: t.secret }, this.go("reset-password")), t?.type === "oauth-failed" && (this.notice = { tone: "error", message: this.t("errorOAuth") }, o.setPending(null)), t?.type === "notice" && (this.notice = {
|
|
2113
|
+
tone: t.tone === "error" ? "error" : t.tone,
|
|
2114
|
+
message: t.message
|
|
2115
|
+
}, o.setPending(null));
|
|
2116
|
+
}
|
|
2117
|
+
/** Navigate between screens and reset transient state. */
|
|
2118
|
+
go(e) {
|
|
2119
|
+
this.step = e, this.error = "", this.busy = !1, this.showPassword = !1, e !== "mfa" && (this.challenge = null), e !== "email-otp" && e !== "phone" && e !== "magic-url" && (this.token = null), this.fire("authui-view", { view: e });
|
|
2120
|
+
}
|
|
2121
|
+
// ───────────────────────────── actions ─────────────────────────────
|
|
2122
|
+
async run(e, t = "link") {
|
|
2123
|
+
if (!this.busy) {
|
|
2124
|
+
this.busy = !0, this.error = "";
|
|
2125
|
+
try {
|
|
2126
|
+
await e();
|
|
2127
|
+
} catch (i) {
|
|
2128
|
+
this.error = Z(i, this.strings, t);
|
|
2129
|
+
} finally {
|
|
2130
|
+
this.busy = !1;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
bind(e) {
|
|
2135
|
+
return (t) => {
|
|
2136
|
+
this[e] = t.target.value;
|
|
2137
|
+
};
|
|
2138
|
+
}
|
|
2139
|
+
// ───────────────────────────── render ─────────────────────────────
|
|
2140
|
+
render() {
|
|
2141
|
+
const e = this.renderStep();
|
|
2142
|
+
return s`
|
|
2143
|
+
<div class="panel ${this.embedded ? "embedded" : ""}" part="panel">
|
|
2144
|
+
${this.renderHeader()}
|
|
2145
|
+
${this.notice ? s`<div class="alert alert-${this.notice.tone}" role="status">
|
|
2146
|
+
${this.notice.tone === "success" ? c.checkCircle : this.notice.tone === "error" ? c.alert : c.info}
|
|
2147
|
+
<div class="alert-body">${this.notice.message}</div>
|
|
2148
|
+
<button
|
|
2149
|
+
class="btn btn-ghost btn-icon dismiss"
|
|
2150
|
+
@click=${() => this.notice = null}
|
|
2151
|
+
aria-label=${this.t("close")}
|
|
2152
|
+
>
|
|
2153
|
+
${c.x}
|
|
2154
|
+
</button>
|
|
2155
|
+
</div>` : n}
|
|
2156
|
+
${e}
|
|
2157
|
+
</div>
|
|
2158
|
+
`;
|
|
2159
|
+
}
|
|
2160
|
+
renderHeader() {
|
|
2161
|
+
const e = this.config?.branding?.logo, t = this.productName;
|
|
2162
|
+
let i = "", r = "";
|
|
2163
|
+
switch (this.step) {
|
|
2164
|
+
case "sign-in":
|
|
2165
|
+
i = this.auth.status === "signed-in" ? this.t("signedInAs") : t ? this.t("signInTitle", { name: t }) : this.t("welcomeBack");
|
|
2166
|
+
break;
|
|
2167
|
+
case "sign-up":
|
|
2168
|
+
i = t ? this.t("signUpTitle", { name: t }) : this.t("createAccount");
|
|
2169
|
+
break;
|
|
2170
|
+
case "forgot-password":
|
|
2171
|
+
case "reset-password":
|
|
2172
|
+
i = this.t("resetPassword");
|
|
2173
|
+
break;
|
|
2174
|
+
case "magic-url":
|
|
2175
|
+
case "email-otp":
|
|
2176
|
+
i = this.t("continueWithEmail");
|
|
2177
|
+
break;
|
|
2178
|
+
case "phone":
|
|
2179
|
+
i = this.t("continueWithPhone");
|
|
2180
|
+
break;
|
|
2181
|
+
case "mfa":
|
|
2182
|
+
i = this.t("mfaTitle"), r = this.t("mfaDescription");
|
|
2183
|
+
break;
|
|
2184
|
+
}
|
|
2185
|
+
return s`
|
|
2186
|
+
<header class="header">
|
|
2187
|
+
${e ? s`<img class="logo" src=${e} alt=${t || "Logo"} />` : n}
|
|
2188
|
+
<h2 class="title" id="authui-title">${i}</h2>
|
|
2189
|
+
${r ? s`<p class="description">${r}</p>` : n}
|
|
2190
|
+
</header>
|
|
2191
|
+
`;
|
|
2192
|
+
}
|
|
2193
|
+
renderError() {
|
|
2194
|
+
return this.error ? s`<div class="alert alert-error" role="alert">
|
|
2195
|
+
${c.alert}
|
|
2196
|
+
<div class="alert-body">${this.error}</div>
|
|
2197
|
+
</div>` : n;
|
|
2198
|
+
}
|
|
2199
|
+
submitButton(e, t = "btn-primary") {
|
|
2200
|
+
return s`<button class="btn ${t} btn-block" type="submit" ?disabled=${this.busy}>
|
|
2201
|
+
${this.busy ? s`<span class="spinner" aria-hidden="true"></span>` : n} ${e}
|
|
2202
|
+
</button>`;
|
|
2203
|
+
}
|
|
2204
|
+
passwordField(e) {
|
|
2205
|
+
return s`
|
|
2206
|
+
<div class="field">
|
|
2207
|
+
<label class="label" for=${e.id}>
|
|
2208
|
+
${e.label}
|
|
2209
|
+
${e.forgot ? s`<button
|
|
2210
|
+
type="button"
|
|
2211
|
+
class="btn btn-link small"
|
|
2212
|
+
@click=${() => this.go("forgot-password")}
|
|
2213
|
+
>
|
|
2214
|
+
${this.t("forgotPassword")}
|
|
2215
|
+
</button>` : n}
|
|
2216
|
+
</label>
|
|
2217
|
+
<div class="input-wrap">
|
|
2218
|
+
<input
|
|
2219
|
+
class="input"
|
|
2220
|
+
id=${e.id}
|
|
2221
|
+
type=${this.showPassword ? "text" : "password"}
|
|
2222
|
+
autocomplete=${e.autocomplete}
|
|
2223
|
+
required
|
|
2224
|
+
minlength="8"
|
|
2225
|
+
.value=${this[e.field]}
|
|
2226
|
+
@input=${this.bind(e.field)}
|
|
2227
|
+
/>
|
|
2228
|
+
<button
|
|
2229
|
+
type="button"
|
|
2230
|
+
class="btn btn-ghost btn-icon"
|
|
2231
|
+
@click=${() => this.showPassword = !this.showPassword}
|
|
2232
|
+
aria-label=${this.showPassword ? "Hide password" : "Show password"}
|
|
2233
|
+
tabindex="-1"
|
|
2234
|
+
>
|
|
2235
|
+
${this.showPassword ? c.eyeOff : c.eye}
|
|
2236
|
+
</button>
|
|
2237
|
+
</div>
|
|
2238
|
+
${e.hint ? s`<p class="hint">${e.hint}</p>` : n}
|
|
2239
|
+
</div>
|
|
2240
|
+
`;
|
|
2241
|
+
}
|
|
2242
|
+
emailField(e = "email") {
|
|
2243
|
+
return s`
|
|
2244
|
+
<div class="field">
|
|
2245
|
+
<label class="label" for="authui-email">${this.t("email")}</label>
|
|
2246
|
+
<input
|
|
2247
|
+
class="input"
|
|
2248
|
+
id="authui-email"
|
|
2249
|
+
type="email"
|
|
2250
|
+
autocomplete=${e}
|
|
2251
|
+
required
|
|
2252
|
+
inputmode="email"
|
|
2253
|
+
.value=${this.email}
|
|
2254
|
+
@input=${this.bind("email")}
|
|
2255
|
+
/>
|
|
2256
|
+
</div>
|
|
2257
|
+
`;
|
|
2258
|
+
}
|
|
2259
|
+
codeField() {
|
|
2260
|
+
return s`
|
|
2261
|
+
<div class="field">
|
|
2262
|
+
<label class="label" for="authui-code">${this.t("code")}</label>
|
|
2263
|
+
<input
|
|
2264
|
+
class="input input-otp"
|
|
2265
|
+
id="authui-code"
|
|
2266
|
+
type="text"
|
|
2267
|
+
inputmode="numeric"
|
|
2268
|
+
autocomplete="one-time-code"
|
|
2269
|
+
required
|
|
2270
|
+
.value=${this.code}
|
|
2271
|
+
@input=${this.bind("code")}
|
|
2272
|
+
/>
|
|
2273
|
+
</div>
|
|
2274
|
+
`;
|
|
2275
|
+
}
|
|
2276
|
+
legal() {
|
|
2277
|
+
const e = this.config?.legal;
|
|
2278
|
+
return !e?.termsUrl && !e?.privacyUrl ? n : s`<p class="legal">
|
|
2279
|
+
${this.t("agreeTo")}
|
|
2280
|
+
${e.termsUrl ? s`<a href=${e.termsUrl} target="_blank" rel="noopener">${this.t("terms")}</a>` : n}
|
|
2281
|
+
${e.termsUrl && e.privacyUrl ? s` ${this.t("and")} ` : n}
|
|
2282
|
+
${e.privacyUrl ? s`<a href=${e.privacyUrl} target="_blank" rel="noopener">${this.t("privacy")}</a>` : n}.
|
|
2283
|
+
</p>`;
|
|
2284
|
+
}
|
|
2285
|
+
backLink(e = "sign-in") {
|
|
2286
|
+
return s`<div class="links">
|
|
2287
|
+
<button type="button" class="btn btn-link" @click=${() => this.go(e)}>
|
|
2288
|
+
${c.arrowLeft} ${this.t("back")}
|
|
2289
|
+
</button>
|
|
2290
|
+
</div>`;
|
|
2291
|
+
}
|
|
2292
|
+
renderStep() {
|
|
2293
|
+
if (!this.auth.configured)
|
|
2294
|
+
return s`<div class="alert alert-error" role="alert">
|
|
2295
|
+
${c.alert}
|
|
2296
|
+
<div class="alert-body">${this.t("errorNotConfigured")}</div>
|
|
2297
|
+
</div>`;
|
|
2298
|
+
if (this.auth.status === "loading")
|
|
2299
|
+
return s`<div class="empty"><span class="spinner"></span></div>`;
|
|
2300
|
+
if (this.auth.status === "signed-in" && this.step !== "mfa") return this.renderSignedIn();
|
|
2301
|
+
switch (this.step) {
|
|
2302
|
+
case "sign-up":
|
|
2303
|
+
return this.renderSignUp();
|
|
2304
|
+
case "forgot-password":
|
|
2305
|
+
return this.renderForgot();
|
|
2306
|
+
case "reset-password":
|
|
2307
|
+
return this.renderReset();
|
|
2308
|
+
case "magic-url":
|
|
2309
|
+
return this.renderMagicUrl();
|
|
2310
|
+
case "email-otp":
|
|
2311
|
+
return this.renderEmailOtp();
|
|
2312
|
+
case "phone":
|
|
2313
|
+
return this.renderPhone();
|
|
2314
|
+
case "mfa":
|
|
2315
|
+
return this.renderMfa();
|
|
2316
|
+
default:
|
|
2317
|
+
return this.renderSignIn();
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
renderSignedIn() {
|
|
2321
|
+
const e = this.auth.user, t = e.name || e.email || e.phone || this.t("guestAccount");
|
|
2322
|
+
return s`
|
|
2323
|
+
<div class="stack">
|
|
2324
|
+
<div class="row">
|
|
2325
|
+
<div class="inline">
|
|
2326
|
+
<span class="avatar">${t[0] ?? "?"}</span>
|
|
2327
|
+
<div class="row-main">
|
|
2328
|
+
<span class="row-title">${t}</span>
|
|
2329
|
+
${e.email && e.name ? s`<span class="row-sub">${e.email}</span>` : n}
|
|
2330
|
+
</div>
|
|
2331
|
+
</div>
|
|
2332
|
+
</div>
|
|
2333
|
+
${this.renderError()}
|
|
2334
|
+
<div class="stack-sm">
|
|
2335
|
+
${this.config?.successUrl ? s`<a class="btn btn-primary btn-block" href=${this.config.successUrl}
|
|
2336
|
+
>${this.t("continue")}</a
|
|
2337
|
+
>` : n}
|
|
2338
|
+
<button
|
|
2339
|
+
class="btn btn-outline btn-block"
|
|
2340
|
+
@click=${() => this.fire("authui-open", { view: "account" })}
|
|
2341
|
+
>
|
|
2342
|
+
${c.settings} ${this.t("manageAccount")}
|
|
2343
|
+
</button>
|
|
2344
|
+
<button class="btn btn-ghost btn-block" @click=${this.onSignOut} ?disabled=${this.busy}>
|
|
2345
|
+
${c.logOut} ${this.t("signOut")}
|
|
2346
|
+
</button>
|
|
2347
|
+
</div>
|
|
2348
|
+
</div>
|
|
2349
|
+
`;
|
|
2350
|
+
}
|
|
2351
|
+
renderProviders() {
|
|
2352
|
+
const e = this.config?.methods?.oauth ?? [];
|
|
2353
|
+
if (e.length === 0) return n;
|
|
2354
|
+
const t = e.length > 2;
|
|
2355
|
+
return s`
|
|
2356
|
+
<div class="providers ${t ? "two" : ""}">
|
|
2357
|
+
${e.map(
|
|
2358
|
+
(i) => s`<button
|
|
2359
|
+
type="button"
|
|
2360
|
+
class="btn btn-outline"
|
|
2361
|
+
@click=${() => this.onOAuth(i)}
|
|
2362
|
+
?disabled=${this.busy}
|
|
2363
|
+
aria-label=${this.t("continueWith", { provider: E(i) })}
|
|
2364
|
+
>
|
|
2365
|
+
${L(i)}
|
|
2366
|
+
<span
|
|
2367
|
+
>${t ? E(i) : this.t("continueWith", { provider: E(i) })}</span
|
|
2368
|
+
>
|
|
2369
|
+
</button>`
|
|
2370
|
+
)}
|
|
2371
|
+
</div>
|
|
2372
|
+
`;
|
|
2373
|
+
}
|
|
2374
|
+
renderSignIn() {
|
|
2375
|
+
const e = this.config?.methods ?? {}, t = e.emailPassword !== !1, i = (e.oauth?.length ?? 0) > 0, r = [
|
|
2376
|
+
e.magicUrl ? { step: "magic-url", icon: c.link, label: this.t("sendMagicLink") } : null,
|
|
2377
|
+
e.emailOtp ? { step: "email-otp", icon: c.mail, label: this.t("continueWithEmail") } : null,
|
|
2378
|
+
e.phone ? { step: "phone", icon: c.smartphone, label: this.t("continueWithPhone") } : null
|
|
2379
|
+
].filter(Boolean);
|
|
2380
|
+
return s`
|
|
2381
|
+
<div class="stack">
|
|
2382
|
+
${this.renderProviders()}
|
|
2383
|
+
${i && (t || r.length > 0) ? s`<div class="separator-text">${this.t("or")}</div>` : n}
|
|
2384
|
+
${t ? s`<form class="form" @submit=${this.onSignIn} novalidate>
|
|
2385
|
+
${this.emailField()}
|
|
2386
|
+
${this.passwordField({ label: this.t("password"), autocomplete: "current-password", id: "authui-password", field: "password", forgot: !0 })}
|
|
2387
|
+
${this.renderError()} ${this.submitButton(this.t("signIn"))}
|
|
2388
|
+
</form>` : this.renderError()}
|
|
2389
|
+
${r.length > 0 ? s`<div class="stack-sm">
|
|
2390
|
+
${r.map(
|
|
2391
|
+
(a) => s`<button
|
|
2392
|
+
type="button"
|
|
2393
|
+
class="btn btn-secondary btn-block"
|
|
2394
|
+
@click=${() => this.go(a.step)}
|
|
2395
|
+
>
|
|
2396
|
+
${a.icon} ${a.label}
|
|
2397
|
+
</button>`
|
|
2398
|
+
)}
|
|
2399
|
+
</div>` : n}
|
|
2400
|
+
${e.anonymous ? s`<button
|
|
2401
|
+
type="button"
|
|
2402
|
+
class="btn btn-ghost btn-block"
|
|
2403
|
+
@click=${this.onGuest}
|
|
2404
|
+
?disabled=${this.busy}
|
|
2405
|
+
>
|
|
2406
|
+
${c.ghost} ${this.t("continueAsGuest")}
|
|
2407
|
+
</button>` : n}
|
|
2408
|
+
${t && this.config?.signUp !== !1 ? s`<div class="links">
|
|
2409
|
+
<span>${this.t("noAccount")}</span>
|
|
2410
|
+
<button type="button" class="btn btn-link" @click=${() => this.go("sign-up")}>
|
|
2411
|
+
${this.t("signUp")}
|
|
2412
|
+
</button>
|
|
2413
|
+
</div>` : n}
|
|
2414
|
+
${this.legal()}
|
|
2415
|
+
</div>
|
|
2416
|
+
`;
|
|
2417
|
+
}
|
|
2418
|
+
renderSignUp() {
|
|
2419
|
+
return s`
|
|
2420
|
+
<div class="stack">
|
|
2421
|
+
${this.renderProviders()}
|
|
2422
|
+
${(this.config?.methods?.oauth?.length ?? 0) > 0 ? s`<div class="separator-text">${this.t("or")}</div>` : n}
|
|
2423
|
+
<form class="form" @submit=${this.onSignUp} novalidate>
|
|
2424
|
+
${this.config?.requireName !== !1 ? s`<div class="field">
|
|
2425
|
+
<label class="label" for="authui-name">${this.t("name")}</label>
|
|
2426
|
+
<input
|
|
2427
|
+
class="input"
|
|
2428
|
+
id="authui-name"
|
|
2429
|
+
type="text"
|
|
2430
|
+
autocomplete="name"
|
|
2431
|
+
required
|
|
2432
|
+
.value=${this.name}
|
|
2433
|
+
@input=${this.bind("name")}
|
|
2434
|
+
/>
|
|
2435
|
+
</div>` : n}
|
|
2436
|
+
${this.emailField()}
|
|
2437
|
+
${this.passwordField({ label: this.t("password"), autocomplete: "new-password", id: "authui-password", field: "password", hint: this.t("passwordHint") })}
|
|
2438
|
+
${this.renderError()} ${this.submitButton(this.t("createAccount"))}
|
|
2439
|
+
</form>
|
|
2440
|
+
<div class="links">
|
|
2441
|
+
<span>${this.t("haveAccount")}</span>
|
|
2442
|
+
<button type="button" class="btn btn-link" @click=${() => this.go("sign-in")}>
|
|
2443
|
+
${this.t("signIn")}
|
|
2444
|
+
</button>
|
|
2445
|
+
</div>
|
|
2446
|
+
${this.legal()}
|
|
2447
|
+
</div>
|
|
2448
|
+
`;
|
|
2449
|
+
}
|
|
2450
|
+
renderForgot() {
|
|
2451
|
+
return s`
|
|
2452
|
+
<div class="stack">
|
|
2453
|
+
<form class="form" @submit=${this.onForgot} novalidate>
|
|
2454
|
+
${this.emailField()} ${this.renderError()} ${this.submitButton(this.t("sendResetLink"))}
|
|
2455
|
+
</form>
|
|
2456
|
+
${this.backLink()}
|
|
2457
|
+
</div>
|
|
2458
|
+
`;
|
|
2459
|
+
}
|
|
2460
|
+
renderReset() {
|
|
2461
|
+
return this.recovery ? s`
|
|
2462
|
+
<div class="stack">
|
|
2463
|
+
<form class="form" @submit=${this.onReset} novalidate>
|
|
2464
|
+
${this.passwordField({ label: this.t("newPassword"), autocomplete: "new-password", id: "authui-password", field: "password", hint: this.t("passwordHint") })}
|
|
2465
|
+
${this.passwordField({ label: this.t("confirmPassword"), autocomplete: "new-password", id: "authui-password-confirm", field: "passwordConfirm" })}
|
|
2466
|
+
${this.renderError()} ${this.submitButton(this.t("resetPassword"))}
|
|
2467
|
+
</form>
|
|
2468
|
+
${this.backLink()}
|
|
2469
|
+
</div>
|
|
2470
|
+
` : s`<div class="stack">
|
|
2471
|
+
<div class="alert alert-error" role="alert">
|
|
2472
|
+
${c.alert}
|
|
2473
|
+
<div class="alert-body">${this.t("errorInvalidToken")}</div>
|
|
2474
|
+
</div>
|
|
2475
|
+
${this.backLink()}
|
|
2476
|
+
</div>`;
|
|
2477
|
+
}
|
|
2478
|
+
phraseBox(e) {
|
|
2479
|
+
return e ? s`<div class="alert alert-info">
|
|
2480
|
+
${c.shield}
|
|
2481
|
+
<div class="alert-title">
|
|
2482
|
+
${this.t("securityPhrase")}: <span class="code">${e}</span>
|
|
2483
|
+
</div>
|
|
2484
|
+
<div class="alert-body">${this.t("securityPhraseHint")}</div>
|
|
2485
|
+
</div>` : n;
|
|
2486
|
+
}
|
|
2487
|
+
renderMagicUrl() {
|
|
2488
|
+
return this.token ? s`<div class="stack">
|
|
2489
|
+
<div class="alert alert-success" role="status">
|
|
2490
|
+
${c.mail}
|
|
2491
|
+
<div class="alert-body">${this.t("magicLinkSent", { email: this.token.target })}</div>
|
|
2492
|
+
</div>
|
|
2493
|
+
${this.phraseBox(this.token.phrase)} ${this.backLink()}
|
|
2494
|
+
</div>` : s`
|
|
2495
|
+
<div class="stack">
|
|
2496
|
+
<form class="form" @submit=${this.onMagicUrl} novalidate>
|
|
2497
|
+
${this.emailField()} ${this.renderError()} ${this.submitButton(this.t("sendMagicLink"))}
|
|
2498
|
+
</form>
|
|
2499
|
+
${this.backLink()}
|
|
2500
|
+
</div>
|
|
2501
|
+
`;
|
|
2502
|
+
}
|
|
2503
|
+
renderCodeEntry() {
|
|
2504
|
+
return s`
|
|
2505
|
+
<div class="alert alert-info" role="status">
|
|
2506
|
+
${c.mail}
|
|
2507
|
+
<div class="alert-body">${this.t("codeSent", { target: this.token.target })}</div>
|
|
2508
|
+
</div>
|
|
2509
|
+
${this.phraseBox(this.token.phrase)}
|
|
2510
|
+
<form class="form" @submit=${this.onVerifyCode} novalidate>
|
|
2511
|
+
${this.codeField()} ${this.renderError()} ${this.submitButton(this.t("verifyCode"))}
|
|
2512
|
+
</form>
|
|
2513
|
+
<div class="links">
|
|
2514
|
+
<button type="button" class="btn btn-link" @click=${() => this.token = null}>
|
|
2515
|
+
${this.t("sendCode")}
|
|
2516
|
+
</button>
|
|
2517
|
+
<span aria-hidden="true">·</span>
|
|
2518
|
+
<button type="button" class="btn btn-link" @click=${() => this.go("sign-in")}>
|
|
2519
|
+
${this.t("back")}
|
|
2520
|
+
</button>
|
|
2521
|
+
</div>
|
|
2522
|
+
`;
|
|
2523
|
+
}
|
|
2524
|
+
renderEmailOtp() {
|
|
2525
|
+
return this.token ? s`<div class="stack">${this.renderCodeEntry()}</div>` : s`
|
|
2526
|
+
<div class="stack">
|
|
2527
|
+
<form class="form" @submit=${this.onEmailOtp} novalidate>
|
|
2528
|
+
${this.emailField()} ${this.renderError()} ${this.submitButton(this.t("sendCode"))}
|
|
2529
|
+
</form>
|
|
2530
|
+
${this.backLink()}
|
|
2531
|
+
</div>
|
|
2532
|
+
`;
|
|
2533
|
+
}
|
|
2534
|
+
renderPhone() {
|
|
2535
|
+
return this.token ? s`<div class="stack">${this.renderCodeEntry()}</div>` : s`
|
|
2536
|
+
<div class="stack">
|
|
2537
|
+
<form class="form" @submit=${this.onPhoneOtp} novalidate>
|
|
2538
|
+
<div class="field">
|
|
2539
|
+
<label class="label" for="authui-phone">${this.t("phone")}</label>
|
|
2540
|
+
<input
|
|
2541
|
+
class="input"
|
|
2542
|
+
id="authui-phone"
|
|
2543
|
+
type="tel"
|
|
2544
|
+
autocomplete="tel"
|
|
2545
|
+
placeholder="+1 555 000 0000"
|
|
2546
|
+
required
|
|
2547
|
+
.value=${this.phone}
|
|
2548
|
+
@input=${this.bind("phone")}
|
|
2549
|
+
/>
|
|
2550
|
+
</div>
|
|
2551
|
+
${this.renderError()} ${this.submitButton(this.t("sendCode"))}
|
|
2552
|
+
</form>
|
|
2553
|
+
${this.backLink()}
|
|
2554
|
+
</div>
|
|
2555
|
+
`;
|
|
2556
|
+
}
|
|
2557
|
+
renderMfa() {
|
|
2558
|
+
const e = this.auth.mfaFactors;
|
|
2559
|
+
if (!this.challenge) {
|
|
2560
|
+
const i = [
|
|
2561
|
+
{
|
|
2562
|
+
factor: "totp",
|
|
2563
|
+
icon: c.smartphone,
|
|
2564
|
+
label: this.t("mfaUseAuthenticator"),
|
|
2565
|
+
available: e?.totp ?? !0
|
|
2566
|
+
},
|
|
2567
|
+
{
|
|
2568
|
+
factor: "email",
|
|
2569
|
+
icon: c.mail,
|
|
2570
|
+
label: this.t("mfaUseEmail"),
|
|
2571
|
+
available: e?.email ?? !0
|
|
2572
|
+
},
|
|
2573
|
+
{
|
|
2574
|
+
factor: "phone",
|
|
2575
|
+
icon: c.phone,
|
|
2576
|
+
label: this.t("mfaUsePhone"),
|
|
2577
|
+
available: e?.phone ?? !0
|
|
2578
|
+
},
|
|
2579
|
+
{
|
|
2580
|
+
factor: "recoverycode",
|
|
2581
|
+
icon: c.key,
|
|
2582
|
+
label: this.t("mfaUseRecoveryCode"),
|
|
2583
|
+
available: e?.recoveryCode ?? !0
|
|
2584
|
+
}
|
|
2585
|
+
];
|
|
2586
|
+
return s`
|
|
2587
|
+
<div class="stack">
|
|
2588
|
+
<div class="stack-sm">
|
|
2589
|
+
${i.filter((r) => r.available).map(
|
|
2590
|
+
(r) => s`<button
|
|
2591
|
+
type="button"
|
|
2592
|
+
class="choice"
|
|
2593
|
+
@click=${() => this.onChooseFactor(r.factor)}
|
|
2594
|
+
?disabled=${this.busy}
|
|
2595
|
+
>
|
|
2596
|
+
${r.icon}<span class="choice-title">${r.label}</span>
|
|
2597
|
+
</button>`
|
|
2598
|
+
)}
|
|
2599
|
+
</div>
|
|
2600
|
+
${this.renderError()}
|
|
2601
|
+
<div class="links">
|
|
2602
|
+
<button type="button" class="btn btn-link" @click=${this.onCancelMfa}>
|
|
2603
|
+
${this.t("cancel")}
|
|
2604
|
+
</button>
|
|
2605
|
+
</div>
|
|
2606
|
+
</div>
|
|
2607
|
+
`;
|
|
2608
|
+
}
|
|
2609
|
+
const t = this.challenge.factor === "recoverycode";
|
|
2610
|
+
return s`
|
|
2611
|
+
<div class="stack">
|
|
2612
|
+
<form class="form" @submit=${this.onVerifyFactor} novalidate>
|
|
2613
|
+
${t ? s`<div class="field">
|
|
2614
|
+
<label class="label" for="authui-code">${this.t("recoveryCode")}</label>
|
|
2615
|
+
<input
|
|
2616
|
+
class="input mono"
|
|
2617
|
+
id="authui-code"
|
|
2618
|
+
type="text"
|
|
2619
|
+
autocomplete="off"
|
|
2620
|
+
required
|
|
2621
|
+
.value=${this.code}
|
|
2622
|
+
@input=${this.bind("code")}
|
|
2623
|
+
/>
|
|
2624
|
+
</div>` : this.codeField()}
|
|
2625
|
+
${this.renderError()} ${this.submitButton(this.t("verifyCode"))}
|
|
2626
|
+
</form>
|
|
2627
|
+
<div class="links">
|
|
2628
|
+
<button type="button" class="btn btn-link" @click=${() => this.challenge = null}>
|
|
2629
|
+
${c.arrowLeft} ${this.t("back")}
|
|
2630
|
+
</button>
|
|
2631
|
+
<span aria-hidden="true">·</span>
|
|
2632
|
+
<button type="button" class="btn btn-link" @click=${this.onCancelMfa}>
|
|
2633
|
+
${this.t("cancel")}
|
|
2634
|
+
</button>
|
|
2635
|
+
</div>
|
|
2636
|
+
</div>
|
|
2637
|
+
`;
|
|
2638
|
+
}
|
|
2639
|
+
};
|
|
2640
|
+
$.styles = [...x.styles, ft];
|
|
2641
|
+
C([
|
|
2642
|
+
g({ type: String })
|
|
2643
|
+
], $.prototype, "view", 2);
|
|
2644
|
+
C([
|
|
2645
|
+
g({ type: Boolean })
|
|
2646
|
+
], $.prototype, "embedded", 2);
|
|
2647
|
+
C([
|
|
2648
|
+
d()
|
|
2649
|
+
], $.prototype, "step", 2);
|
|
2650
|
+
C([
|
|
2651
|
+
d()
|
|
2652
|
+
], $.prototype, "busy", 2);
|
|
2653
|
+
C([
|
|
2654
|
+
d()
|
|
2655
|
+
], $.prototype, "error", 2);
|
|
2656
|
+
C([
|
|
2657
|
+
d()
|
|
2658
|
+
], $.prototype, "notice", 2);
|
|
2659
|
+
C([
|
|
2660
|
+
d()
|
|
2661
|
+
], $.prototype, "showPassword", 2);
|
|
2662
|
+
C([
|
|
2663
|
+
d()
|
|
2664
|
+
], $.prototype, "token", 2);
|
|
2665
|
+
C([
|
|
2666
|
+
d()
|
|
2667
|
+
], $.prototype, "challenge", 2);
|
|
2668
|
+
C([
|
|
2669
|
+
d()
|
|
2670
|
+
], $.prototype, "recovery", 2);
|
|
2671
|
+
C([
|
|
2672
|
+
X("form input:not([type=hidden])")
|
|
2673
|
+
], $.prototype, "firstInput", 2);
|
|
2674
|
+
$ = C([
|
|
2675
|
+
S("authui-sign-in")
|
|
2676
|
+
], $);
|
|
2677
|
+
var vt = Object.defineProperty, yt = Object.getOwnPropertyDescriptor, m = (e, t, i, r) => {
|
|
2678
|
+
for (var a = r > 1 ? void 0 : r ? yt(t, i) : t, u = e.length - 1, h; u >= 0; u--)
|
|
2679
|
+
(h = e[u]) && (a = (r ? h(t, i, a) : h(a)) || a);
|
|
2680
|
+
return r && a && vt(t, i, a), a;
|
|
2681
|
+
};
|
|
2682
|
+
let p = class extends x {
|
|
2683
|
+
constructor() {
|
|
2684
|
+
super(...arguments), this.embedded = !1, this.tab = "profile", this.active = "profile", this.busy = "", this.notice = null, this.errors = {}, this.nameInput = "", this.emailInput = "", this.emailPassword = "", this.phoneInput = "", this.phonePassword = "", this.phoneCode = "", this.phoneCodeSent = !1, this.guestName = "", this.oldPassword = "", this.newPassword = "", this.newPasswordConfirm = "", this.authenticator = null, this.authenticatorCode = "", this.factors = null, this.recoveryCodes = null, this.stepUp = null, this.stepUpCode = "", this.copied = !1, this.sessions = null, this.identities = null, this.logs = null, this.logsSupported = !0, this.confirmDelete = !1, this.factorsLoading = !1, this.onUpdateName = (e) => {
|
|
2685
|
+
e.preventDefault(), this.run("name", () => o.updateName(this.nameInput), this.t("done"));
|
|
2686
|
+
}, this.onUpdateEmail = (e) => {
|
|
2687
|
+
e.preventDefault(), this.run(
|
|
2688
|
+
"email",
|
|
2689
|
+
async () => {
|
|
2690
|
+
await o.updateEmail(this.emailInput, this.emailPassword), this.emailPassword = "";
|
|
2691
|
+
},
|
|
2692
|
+
this.t("done")
|
|
2693
|
+
);
|
|
2694
|
+
}, this.onUpdatePhone = (e) => {
|
|
2695
|
+
e.preventDefault(), this.run(
|
|
2696
|
+
"phone",
|
|
2697
|
+
async () => {
|
|
2698
|
+
await o.updatePhone(this.phoneInput, this.phonePassword), this.phonePassword = "";
|
|
2699
|
+
},
|
|
2700
|
+
this.t("done")
|
|
2701
|
+
);
|
|
2702
|
+
}, this.onConvertGuest = (e) => {
|
|
2703
|
+
e.preventDefault(), this.run(
|
|
2704
|
+
"guest",
|
|
2705
|
+
async () => {
|
|
2706
|
+
await o.convertGuest(this.emailInput, this.emailPassword, this.guestName), this.emailPassword = "";
|
|
2707
|
+
},
|
|
2708
|
+
this.t("done")
|
|
2709
|
+
);
|
|
2710
|
+
}, this.onSendVerification = () => {
|
|
2711
|
+
this.run("verify", () => o.sendEmailVerification(), this.t("verificationSent"));
|
|
2712
|
+
}, this.onSendPhoneVerification = () => {
|
|
2713
|
+
this.run("verify-phone", async () => {
|
|
2714
|
+
await o.sendPhoneVerification(), this.phoneCodeSent = !0;
|
|
2715
|
+
});
|
|
2716
|
+
}, this.onConfirmPhoneVerification = (e) => {
|
|
2717
|
+
e.preventDefault(), this.run(
|
|
2718
|
+
"verify-phone-code",
|
|
2719
|
+
async () => {
|
|
2720
|
+
await o.confirmPhoneVerification(this.phoneCode), this.phoneCode = "", this.phoneCodeSent = !1;
|
|
2721
|
+
},
|
|
2722
|
+
this.t("done")
|
|
2723
|
+
);
|
|
2724
|
+
}, this.onChangePassword = (e) => {
|
|
2725
|
+
if (e.preventDefault(), this.newPassword !== this.newPasswordConfirm) {
|
|
2726
|
+
this.errors = { ...this.errors, password: this.t("errorPasswordMismatch") };
|
|
2727
|
+
return;
|
|
2728
|
+
}
|
|
2729
|
+
this.run(
|
|
2730
|
+
"password",
|
|
2731
|
+
async () => {
|
|
2732
|
+
await o.updatePassword(this.newPassword, this.oldPassword), this.oldPassword = this.newPassword = this.newPasswordConfirm = "";
|
|
2733
|
+
},
|
|
2734
|
+
this.t("passwordUpdated")
|
|
2735
|
+
);
|
|
2736
|
+
}, this.onToggleMfa = () => {
|
|
2737
|
+
const e = !this.user?.mfa;
|
|
2738
|
+
this.run("mfa", async () => {
|
|
2739
|
+
await o.setMfaEnabled(e), await this.loadFactors();
|
|
2740
|
+
});
|
|
2741
|
+
}, this.onAddAuthenticator = () => {
|
|
2742
|
+
this.run("authenticator", async () => {
|
|
2743
|
+
this.authenticator = await o.addAuthenticator(), this.authenticatorCode = "";
|
|
2744
|
+
});
|
|
2745
|
+
}, this.onVerifyAuthenticator = (e) => {
|
|
2746
|
+
e.preventDefault(), this.run(
|
|
2747
|
+
"authenticator-code",
|
|
2748
|
+
async () => {
|
|
2749
|
+
await o.verifyAuthenticator(this.authenticatorCode), this.authenticator = null, this.authenticatorCode = "", await this.loadFactors();
|
|
2750
|
+
},
|
|
2751
|
+
this.t("done")
|
|
2752
|
+
);
|
|
2753
|
+
}, this.onRemoveAuthenticator = () => {
|
|
2754
|
+
this.run("remove-authenticator", async () => {
|
|
2755
|
+
await o.removeAuthenticator(), await this.loadFactors();
|
|
2756
|
+
});
|
|
2757
|
+
}, this.onRecoveryCodes = () => {
|
|
2758
|
+
this.run("recovery", async () => {
|
|
2759
|
+
try {
|
|
2760
|
+
this.recoveryCodes = await o.createRecoveryCodes();
|
|
2761
|
+
} catch (e) {
|
|
2762
|
+
if (!F(e, b.recoveryCodesExist)) throw e;
|
|
2763
|
+
this.recoveryCodes = await o.getRecoveryCodes();
|
|
2764
|
+
}
|
|
2765
|
+
await this.loadFactors();
|
|
2766
|
+
});
|
|
2767
|
+
}, this.onRegenerateRecoveryCodes = () => {
|
|
2768
|
+
this.run("recovery", async () => {
|
|
2769
|
+
this.recoveryCodes = await o.regenerateRecoveryCodes();
|
|
2770
|
+
});
|
|
2771
|
+
}, this.onCopyCodes = async () => {
|
|
2772
|
+
if (this.recoveryCodes)
|
|
2773
|
+
try {
|
|
2774
|
+
await navigator.clipboard.writeText(this.recoveryCodes.join(`
|
|
2775
|
+
`)), this.copied = !0, setTimeout(() => this.copied = !1, 1500);
|
|
2776
|
+
} catch {
|
|
2777
|
+
}
|
|
2778
|
+
}, this.onStepUpFactor = (e) => {
|
|
2779
|
+
this.run("stepup", async () => {
|
|
2780
|
+
const t = await o.createMfaChallenge(e);
|
|
2781
|
+
this.stepUp = { ...this.stepUp, challenge: { id: t.$id, factor: e } }, this.stepUpCode = "";
|
|
2782
|
+
});
|
|
2783
|
+
}, this.onStepUpVerify = (e) => {
|
|
2784
|
+
e.preventDefault();
|
|
2785
|
+
const t = this.stepUp;
|
|
2786
|
+
t?.challenge && this.run("stepup-code", async () => {
|
|
2787
|
+
await o.completeMfaChallenge(t.challenge.id, this.stepUpCode, { signIn: !1 }), this.stepUp = null, this.stepUpCode = "", await t.retry();
|
|
2788
|
+
});
|
|
2789
|
+
}, this.onDeleteSession = (e) => {
|
|
2790
|
+
this.run(`session-${e}`, async () => {
|
|
2791
|
+
await o.signOut(e), this.sessions = (this.sessions ?? []).filter((t) => t.$id !== e);
|
|
2792
|
+
});
|
|
2793
|
+
}, this.onSignOutAll = () => {
|
|
2794
|
+
this.run("sessions-all", () => o.signOutEverywhere());
|
|
2795
|
+
}, this.onDeleteIdentity = (e) => {
|
|
2796
|
+
this.run(`identity-${e}`, async () => {
|
|
2797
|
+
await o.deleteIdentity(e), this.identities = (this.identities ?? []).filter((t) => t.$id !== e);
|
|
2798
|
+
});
|
|
2799
|
+
}, this.onDeleteAccount = () => {
|
|
2800
|
+
this.run("delete", () => o.deleteAccount());
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
connectedCallback() {
|
|
2804
|
+
super.connectedCallback(), this.active = this.tab, this.hydrate();
|
|
2805
|
+
}
|
|
2806
|
+
willUpdate(e) {
|
|
2807
|
+
e.has("tab") && e.get("tab") !== void 0 && (this.active = this.tab), e.has("auth") && this.hydrate(), this.ensureLoaded();
|
|
2808
|
+
}
|
|
2809
|
+
/** Lazily load data for the active tab once a user is available. */
|
|
2810
|
+
ensureLoaded() {
|
|
2811
|
+
!this.user || this.busy || (this.active === "sessions" && this.sessions === null ? this.loadSessions() : this.active === "connections" && this.identities === null ? this.loadIdentities() : this.active === "activity" && this.logs === null ? this.loadLogs() : this.active === "security" && this.factors === null && this.loadFactors());
|
|
2812
|
+
}
|
|
2813
|
+
hydrate() {
|
|
2814
|
+
const e = this.auth.user;
|
|
2815
|
+
e && (this.nameInput || (this.nameInput = e.name ?? ""), this.emailInput || (this.emailInput = e.email ?? ""), this.phoneInput || (this.phoneInput = e.phone ?? ""));
|
|
2816
|
+
}
|
|
2817
|
+
get user() {
|
|
2818
|
+
return this.auth.user;
|
|
2819
|
+
}
|
|
2820
|
+
get isGuest() {
|
|
2821
|
+
const e = this.user;
|
|
2822
|
+
return !!e && !e.email && !e.phone;
|
|
2823
|
+
}
|
|
2824
|
+
select(e) {
|
|
2825
|
+
this.active = e, this.notice = null, this.errors = {};
|
|
2826
|
+
}
|
|
2827
|
+
/** Run an action with a busy key, surfacing errors under that key. Handles MFA step-up. */
|
|
2828
|
+
async run(e, t, i) {
|
|
2829
|
+
if (!this.busy) {
|
|
2830
|
+
this.busy = e, this.errors = { ...this.errors, [e]: "" };
|
|
2831
|
+
try {
|
|
2832
|
+
await t(), i && (this.notice = { tone: "success", message: i });
|
|
2833
|
+
} catch (r) {
|
|
2834
|
+
F(r, b.challengeRequired) ? this.stepUp = { retry: () => this.run(e, t, i) } : this.errors = {
|
|
2835
|
+
...this.errors,
|
|
2836
|
+
[e]: Z(r, this.strings, e.includes("code") ? "code" : "link")
|
|
2837
|
+
};
|
|
2838
|
+
} finally {
|
|
2839
|
+
this.busy = "";
|
|
2840
|
+
}
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
// ─────────────────────────── loaders ───────────────────────────
|
|
2844
|
+
async loadSessions() {
|
|
2845
|
+
await this.run("sessions", async () => {
|
|
2846
|
+
this.sessions = await o.listSessions();
|
|
2847
|
+
});
|
|
2848
|
+
}
|
|
2849
|
+
async loadIdentities() {
|
|
2850
|
+
await this.run("identities", async () => {
|
|
2851
|
+
this.identities = await o.listIdentities();
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2854
|
+
async loadLogs() {
|
|
2855
|
+
this.busy = "logs";
|
|
2856
|
+
try {
|
|
2857
|
+
this.logs = await o.listLogs();
|
|
2858
|
+
} catch {
|
|
2859
|
+
this.logsSupported = !1, this.logs = [];
|
|
2860
|
+
} finally {
|
|
2861
|
+
this.busy = "";
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
async loadFactors() {
|
|
2865
|
+
if (!this.factorsLoading) {
|
|
2866
|
+
this.factorsLoading = !0;
|
|
2867
|
+
try {
|
|
2868
|
+
this.factors = await o.listMfaFactors();
|
|
2869
|
+
} catch {
|
|
2870
|
+
this.factors = {
|
|
2871
|
+
totp: !1,
|
|
2872
|
+
phone: !1,
|
|
2873
|
+
email: !1,
|
|
2874
|
+
recoveryCode: !1,
|
|
2875
|
+
custom: !1
|
|
2876
|
+
};
|
|
2877
|
+
} finally {
|
|
2878
|
+
this.factorsLoading = !1;
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
bind(e) {
|
|
2883
|
+
return (t) => {
|
|
2884
|
+
this[e] = t.target.value;
|
|
2885
|
+
};
|
|
2886
|
+
}
|
|
2887
|
+
// ─────────────────────────── render ───────────────────────────
|
|
2888
|
+
render() {
|
|
2889
|
+
if (!this.auth.configured)
|
|
2890
|
+
return s`<div class="alert alert-error" role="alert">
|
|
2891
|
+
${c.alert}
|
|
2892
|
+
<div class="alert-body">${this.t("errorNotConfigured")}</div>
|
|
2893
|
+
</div>`;
|
|
2894
|
+
if (this.auth.status === "loading")
|
|
2895
|
+
return s`<div class="empty"><span class="spinner"></span></div>`;
|
|
2896
|
+
if (!this.user)
|
|
2897
|
+
return s`<div class="panel ${this.embedded ? "embedded" : ""}">
|
|
2898
|
+
<authui-sign-in embedded></authui-sign-in>
|
|
2899
|
+
</div>`;
|
|
2900
|
+
const e = [
|
|
2901
|
+
{ id: "profile", label: this.t("profile") },
|
|
2902
|
+
{ id: "security", label: this.t("security") },
|
|
2903
|
+
{ id: "sessions", label: this.t("sessions") },
|
|
2904
|
+
{ id: "connections", label: this.t("connections") },
|
|
2905
|
+
...this.logsSupported ? [{ id: "activity", label: this.t("activity") }] : []
|
|
2906
|
+
];
|
|
2907
|
+
return s`
|
|
2908
|
+
<div class="panel ${this.embedded ? "embedded" : ""}" part="panel">
|
|
2909
|
+
${this.renderIdentity()}
|
|
2910
|
+
<div class="tabs" role="tablist">
|
|
2911
|
+
${e.map(
|
|
2912
|
+
(t) => s`<button
|
|
2913
|
+
class="tab"
|
|
2914
|
+
role="tab"
|
|
2915
|
+
aria-selected=${this.active === t.id ? "true" : "false"}
|
|
2916
|
+
@click=${() => this.select(t.id)}
|
|
2917
|
+
>
|
|
2918
|
+
${t.label}
|
|
2919
|
+
</button>`
|
|
2920
|
+
)}
|
|
2921
|
+
</div>
|
|
2922
|
+
${this.notice ? s`<div class="alert alert-${this.notice.tone}" role="status">
|
|
2923
|
+
${this.notice.tone === "success" ? c.checkCircle : c.info}
|
|
2924
|
+
<div class="alert-body">${this.notice.message}</div>
|
|
2925
|
+
</div>` : n}
|
|
2926
|
+
${this.stepUp ? this.renderStepUp() : this.renderTab()}
|
|
2927
|
+
</div>
|
|
2928
|
+
`;
|
|
2929
|
+
}
|
|
2930
|
+
renderIdentity() {
|
|
2931
|
+
const e = this.user, t = e.name || e.email || e.phone || this.t("guestAccount");
|
|
2932
|
+
return s`
|
|
2933
|
+
<div class="between">
|
|
2934
|
+
<div class="identity">
|
|
2935
|
+
<span class="avatar">${t[0] ?? "?"}</span>
|
|
2936
|
+
<div class="row-main">
|
|
2937
|
+
<span class="row-title">
|
|
2938
|
+
${t}
|
|
2939
|
+
${e.mfa ? s`<span class="badge badge-success">${c.shieldCheck} MFA</span>` : n}
|
|
2940
|
+
</span>
|
|
2941
|
+
${e.email && e.name ? s`<span class="row-sub">${e.email}</span>` : n}
|
|
2942
|
+
</div>
|
|
2943
|
+
</div>
|
|
2944
|
+
<button class="btn btn-outline btn-sm" @click=${() => o.signOut()}>
|
|
2945
|
+
${c.logOut} ${this.t("signOut")}
|
|
2946
|
+
</button>
|
|
2947
|
+
</div>
|
|
2948
|
+
`;
|
|
2949
|
+
}
|
|
2950
|
+
renderTab() {
|
|
2951
|
+
switch (this.active) {
|
|
2952
|
+
case "security":
|
|
2953
|
+
return this.renderSecurity();
|
|
2954
|
+
case "sessions":
|
|
2955
|
+
return this.renderSessions();
|
|
2956
|
+
case "connections":
|
|
2957
|
+
return this.renderConnections();
|
|
2958
|
+
case "activity":
|
|
2959
|
+
return this.renderActivity();
|
|
2960
|
+
default:
|
|
2961
|
+
return this.renderProfile();
|
|
2962
|
+
}
|
|
2963
|
+
}
|
|
2964
|
+
error(e) {
|
|
2965
|
+
const t = this.errors[e];
|
|
2966
|
+
return t ? s`<div class="alert alert-error" role="alert">
|
|
2967
|
+
${c.alert}
|
|
2968
|
+
<div class="alert-body">${t}</div>
|
|
2969
|
+
</div>` : n;
|
|
2970
|
+
}
|
|
2971
|
+
spinner(e) {
|
|
2972
|
+
return this.busy === e ? s`<span class="spinner" aria-hidden="true"></span>` : n;
|
|
2973
|
+
}
|
|
2974
|
+
card(e, t, i, r, a = !1) {
|
|
2975
|
+
return s`<section class="card ${a ? "card-danger" : ""}">
|
|
2976
|
+
<div class="card-header">
|
|
2977
|
+
<h3 class="card-title">${e}</h3>
|
|
2978
|
+
${t ? s`<p class="card-description">${t}</p>` : n}
|
|
2979
|
+
</div>
|
|
2980
|
+
<div class="card-body">${i}</div>
|
|
2981
|
+
${r ? s`<div class="card-footer">${r}</div>` : n}
|
|
2982
|
+
</section>`;
|
|
2983
|
+
}
|
|
2984
|
+
verifiedBadge(e) {
|
|
2985
|
+
return e ? s`<span class="badge badge-success">${c.check} ${this.t("verified")}</span>` : s`<span class="badge badge-warning">${this.t("unverified")}</span>`;
|
|
2986
|
+
}
|
|
2987
|
+
// ── Profile ──
|
|
2988
|
+
renderProfile() {
|
|
2989
|
+
const e = this.user;
|
|
2990
|
+
return this.isGuest ? s`<div class="section">
|
|
2991
|
+
${this.card(
|
|
2992
|
+
this.t("guestAccount"),
|
|
2993
|
+
this.t("guestAccountDescription"),
|
|
2994
|
+
s`<form class="form" id="guest-form" @submit=${this.onConvertGuest} novalidate>
|
|
2995
|
+
<div class="field">
|
|
2996
|
+
<label class="label" for="guest-name">${this.t("name")}</label>
|
|
2997
|
+
<input
|
|
2998
|
+
class="input"
|
|
2999
|
+
id="guest-name"
|
|
3000
|
+
.value=${this.guestName}
|
|
3001
|
+
@input=${this.bind("guestName")}
|
|
3002
|
+
autocomplete="name"
|
|
3003
|
+
/>
|
|
3004
|
+
</div>
|
|
3005
|
+
<div class="field">
|
|
3006
|
+
<label class="label" for="guest-email">${this.t("email")}</label>
|
|
3007
|
+
<input
|
|
3008
|
+
class="input"
|
|
3009
|
+
id="guest-email"
|
|
3010
|
+
type="email"
|
|
3011
|
+
required
|
|
3012
|
+
.value=${this.emailInput}
|
|
3013
|
+
@input=${this.bind("emailInput")}
|
|
3014
|
+
autocomplete="email"
|
|
3015
|
+
/>
|
|
3016
|
+
</div>
|
|
3017
|
+
<div class="field">
|
|
3018
|
+
<label class="label" for="guest-password">${this.t("password")}</label>
|
|
3019
|
+
<input
|
|
3020
|
+
class="input"
|
|
3021
|
+
id="guest-password"
|
|
3022
|
+
type="password"
|
|
3023
|
+
required
|
|
3024
|
+
minlength="8"
|
|
3025
|
+
.value=${this.emailPassword}
|
|
3026
|
+
@input=${this.bind("emailPassword")}
|
|
3027
|
+
autocomplete="new-password"
|
|
3028
|
+
/>
|
|
3029
|
+
<p class="hint">${this.t("passwordHint")}</p>
|
|
3030
|
+
</div>
|
|
3031
|
+
${this.error("guest")}
|
|
3032
|
+
</form>`,
|
|
3033
|
+
s`<button
|
|
3034
|
+
class="btn btn-primary btn-sm"
|
|
3035
|
+
type="submit"
|
|
3036
|
+
form="guest-form"
|
|
3037
|
+
?disabled=${!!this.busy}
|
|
3038
|
+
>
|
|
3039
|
+
${this.spinner("guest")} ${this.t("createAccount")}
|
|
3040
|
+
</button>`
|
|
3041
|
+
)}
|
|
3042
|
+
</div>` : s`<div class="section">
|
|
3043
|
+
${this.card(
|
|
3044
|
+
this.t("name"),
|
|
3045
|
+
void 0,
|
|
3046
|
+
s`<form class="form" id="name-form" @submit=${this.onUpdateName} novalidate>
|
|
3047
|
+
<div class="field">
|
|
3048
|
+
<label class="label" for="acc-name">${this.t("name")}</label>
|
|
3049
|
+
<input
|
|
3050
|
+
class="input"
|
|
3051
|
+
id="acc-name"
|
|
3052
|
+
.value=${this.nameInput}
|
|
3053
|
+
@input=${this.bind("nameInput")}
|
|
3054
|
+
autocomplete="name"
|
|
3055
|
+
required
|
|
3056
|
+
/>
|
|
3057
|
+
</div>
|
|
3058
|
+
${this.error("name")}
|
|
3059
|
+
</form>`,
|
|
3060
|
+
s`<button
|
|
3061
|
+
class="btn btn-primary btn-sm"
|
|
3062
|
+
type="submit"
|
|
3063
|
+
form="name-form"
|
|
3064
|
+
?disabled=${!!this.busy || this.nameInput === e.name}
|
|
3065
|
+
>
|
|
3066
|
+
${this.spinner("name")} ${this.t("update")}
|
|
3067
|
+
</button>`
|
|
3068
|
+
)}
|
|
3069
|
+
${this.card(
|
|
3070
|
+
this.t("email"),
|
|
3071
|
+
void 0,
|
|
3072
|
+
s`<form class="form" id="email-form" @submit=${this.onUpdateEmail} novalidate>
|
|
3073
|
+
<div class="field">
|
|
3074
|
+
<label class="label" for="acc-email"
|
|
3075
|
+
>${this.t("email")}
|
|
3076
|
+
${e.email ? this.verifiedBadge(e.emailVerification) : n}</label
|
|
3077
|
+
>
|
|
3078
|
+
<input
|
|
3079
|
+
class="input"
|
|
3080
|
+
id="acc-email"
|
|
3081
|
+
type="email"
|
|
3082
|
+
.value=${this.emailInput}
|
|
3083
|
+
@input=${this.bind("emailInput")}
|
|
3084
|
+
autocomplete="email"
|
|
3085
|
+
required
|
|
3086
|
+
/>
|
|
3087
|
+
</div>
|
|
3088
|
+
${this.emailInput !== e.email ? s`<div class="field">
|
|
3089
|
+
<label class="label" for="acc-email-password">${this.t("currentPassword")}</label>
|
|
3090
|
+
<input
|
|
3091
|
+
class="input"
|
|
3092
|
+
id="acc-email-password"
|
|
3093
|
+
type="password"
|
|
3094
|
+
.value=${this.emailPassword}
|
|
3095
|
+
@input=${this.bind("emailPassword")}
|
|
3096
|
+
autocomplete="current-password"
|
|
3097
|
+
required
|
|
3098
|
+
/>
|
|
3099
|
+
</div>` : n}
|
|
3100
|
+
${this.error("email")} ${this.error("verify")}
|
|
3101
|
+
</form>`,
|
|
3102
|
+
s`
|
|
3103
|
+
${e.email && !e.emailVerification ? s`<button
|
|
3104
|
+
class="btn btn-outline btn-sm"
|
|
3105
|
+
type="button"
|
|
3106
|
+
@click=${this.onSendVerification}
|
|
3107
|
+
?disabled=${!!this.busy}
|
|
3108
|
+
>
|
|
3109
|
+
${this.spinner("verify")} ${this.t("verifyEmail")}
|
|
3110
|
+
</button>` : n}
|
|
3111
|
+
<button
|
|
3112
|
+
class="btn btn-primary btn-sm"
|
|
3113
|
+
type="submit"
|
|
3114
|
+
form="email-form"
|
|
3115
|
+
?disabled=${!!this.busy || this.emailInput === e.email}
|
|
3116
|
+
>
|
|
3117
|
+
${this.spinner("email")} ${this.t("update")}
|
|
3118
|
+
</button>
|
|
3119
|
+
`
|
|
3120
|
+
)}
|
|
3121
|
+
${this.card(
|
|
3122
|
+
this.t("phone"),
|
|
3123
|
+
void 0,
|
|
3124
|
+
s`<form class="form" id="phone-form" @submit=${this.onUpdatePhone} novalidate>
|
|
3125
|
+
<div class="field">
|
|
3126
|
+
<label class="label" for="acc-phone"
|
|
3127
|
+
>${this.t("phone")}
|
|
3128
|
+
${e.phone ? this.verifiedBadge(e.phoneVerification) : n}</label
|
|
3129
|
+
>
|
|
3130
|
+
<input
|
|
3131
|
+
class="input"
|
|
3132
|
+
id="acc-phone"
|
|
3133
|
+
type="tel"
|
|
3134
|
+
placeholder="+1 555 000 0000"
|
|
3135
|
+
.value=${this.phoneInput}
|
|
3136
|
+
@input=${this.bind("phoneInput")}
|
|
3137
|
+
autocomplete="tel"
|
|
3138
|
+
/>
|
|
3139
|
+
</div>
|
|
3140
|
+
${this.phoneInput !== e.phone ? s`<div class="field">
|
|
3141
|
+
<label class="label" for="acc-phone-password">${this.t("currentPassword")}</label>
|
|
3142
|
+
<input
|
|
3143
|
+
class="input"
|
|
3144
|
+
id="acc-phone-password"
|
|
3145
|
+
type="password"
|
|
3146
|
+
.value=${this.phonePassword}
|
|
3147
|
+
@input=${this.bind("phonePassword")}
|
|
3148
|
+
autocomplete="current-password"
|
|
3149
|
+
required
|
|
3150
|
+
/>
|
|
3151
|
+
</div>` : n}
|
|
3152
|
+
${this.phoneCodeSent ? s`<div class="field">
|
|
3153
|
+
<label class="label" for="acc-phone-code">${this.t("code")}</label>
|
|
3154
|
+
<input
|
|
3155
|
+
class="input input-otp"
|
|
3156
|
+
id="acc-phone-code"
|
|
3157
|
+
inputmode="numeric"
|
|
3158
|
+
autocomplete="one-time-code"
|
|
3159
|
+
.value=${this.phoneCode}
|
|
3160
|
+
@input=${this.bind("phoneCode")}
|
|
3161
|
+
/>
|
|
3162
|
+
</div>` : n}
|
|
3163
|
+
${this.error("phone")} ${this.error("verify-phone")} ${this.error("verify-phone-code")}
|
|
3164
|
+
</form>`,
|
|
3165
|
+
s`
|
|
3166
|
+
${e.phone && !e.phoneVerification && !this.phoneCodeSent ? s`<button
|
|
3167
|
+
class="btn btn-outline btn-sm"
|
|
3168
|
+
type="button"
|
|
3169
|
+
@click=${this.onSendPhoneVerification}
|
|
3170
|
+
?disabled=${!!this.busy}
|
|
3171
|
+
>
|
|
3172
|
+
${this.spinner("verify-phone")} ${this.t("sendCode")}
|
|
3173
|
+
</button>` : n}
|
|
3174
|
+
${this.phoneCodeSent ? s`<button
|
|
3175
|
+
class="btn btn-outline btn-sm"
|
|
3176
|
+
type="button"
|
|
3177
|
+
@click=${this.onConfirmPhoneVerification}
|
|
3178
|
+
?disabled=${!!this.busy}
|
|
3179
|
+
>
|
|
3180
|
+
${this.spinner("verify-phone-code")} ${this.t("verifyCode")}
|
|
3181
|
+
</button>` : n}
|
|
3182
|
+
<button
|
|
3183
|
+
class="btn btn-primary btn-sm"
|
|
3184
|
+
type="submit"
|
|
3185
|
+
form="phone-form"
|
|
3186
|
+
?disabled=${!!this.busy || this.phoneInput === e.phone}
|
|
3187
|
+
>
|
|
3188
|
+
${this.spinner("phone")} ${this.t("update")}
|
|
3189
|
+
</button>
|
|
3190
|
+
`
|
|
3191
|
+
)}
|
|
3192
|
+
${this.renderDanger()}
|
|
3193
|
+
</div>`;
|
|
3194
|
+
}
|
|
3195
|
+
renderDanger() {
|
|
3196
|
+
return this.card(
|
|
3197
|
+
this.t("deleteAccount"),
|
|
3198
|
+
this.t("deleteAccountDescription"),
|
|
3199
|
+
s`${this.error("delete")}
|
|
3200
|
+
${this.confirmDelete ? s`<div class="inline">
|
|
3201
|
+
<button
|
|
3202
|
+
class="btn btn-destructive btn-sm"
|
|
3203
|
+
@click=${this.onDeleteAccount}
|
|
3204
|
+
?disabled=${!!this.busy}
|
|
3205
|
+
>
|
|
3206
|
+
${this.spinner("delete")} ${this.t("deleteAccountConfirm")}
|
|
3207
|
+
</button>
|
|
3208
|
+
<button class="btn btn-ghost btn-sm" @click=${() => this.confirmDelete = !1}>
|
|
3209
|
+
${this.t("cancel")}
|
|
3210
|
+
</button>
|
|
3211
|
+
</div>` : s`<button
|
|
3212
|
+
class="btn btn-outline btn-sm warn"
|
|
3213
|
+
@click=${() => this.confirmDelete = !0}
|
|
3214
|
+
>
|
|
3215
|
+
${c.userX} ${this.t("deleteAccount")}
|
|
3216
|
+
</button>`}`,
|
|
3217
|
+
void 0,
|
|
3218
|
+
!0
|
|
3219
|
+
);
|
|
3220
|
+
}
|
|
3221
|
+
// ── Security ──
|
|
3222
|
+
renderSecurity() {
|
|
3223
|
+
const e = this.user, t = this.config?.mfa !== !1;
|
|
3224
|
+
return s`<div class="section">
|
|
3225
|
+
${this.isGuest ? n : this.card(
|
|
3226
|
+
this.t("changePassword"),
|
|
3227
|
+
void 0,
|
|
3228
|
+
s`<form
|
|
3229
|
+
class="form"
|
|
3230
|
+
id="password-form"
|
|
3231
|
+
@submit=${this.onChangePassword}
|
|
3232
|
+
novalidate
|
|
3233
|
+
>
|
|
3234
|
+
${e.passwordUpdate ? s`<div class="field">
|
|
3235
|
+
<label class="label" for="acc-old-password"
|
|
3236
|
+
>${this.t("currentPassword")}</label
|
|
3237
|
+
>
|
|
3238
|
+
<input
|
|
3239
|
+
class="input"
|
|
3240
|
+
id="acc-old-password"
|
|
3241
|
+
type="password"
|
|
3242
|
+
.value=${this.oldPassword}
|
|
3243
|
+
@input=${this.bind("oldPassword")}
|
|
3244
|
+
autocomplete="current-password"
|
|
3245
|
+
/>
|
|
3246
|
+
</div>` : n}
|
|
3247
|
+
<div class="field">
|
|
3248
|
+
<label class="label" for="acc-new-password">${this.t("newPassword")}</label>
|
|
3249
|
+
<input
|
|
3250
|
+
class="input"
|
|
3251
|
+
id="acc-new-password"
|
|
3252
|
+
type="password"
|
|
3253
|
+
required
|
|
3254
|
+
minlength="8"
|
|
3255
|
+
.value=${this.newPassword}
|
|
3256
|
+
@input=${this.bind("newPassword")}
|
|
3257
|
+
autocomplete="new-password"
|
|
3258
|
+
/>
|
|
3259
|
+
<p class="hint">${this.t("passwordHint")}</p>
|
|
3260
|
+
</div>
|
|
3261
|
+
<div class="field">
|
|
3262
|
+
<label class="label" for="acc-new-password-confirm"
|
|
3263
|
+
>${this.t("confirmPassword")}</label
|
|
3264
|
+
>
|
|
3265
|
+
<input
|
|
3266
|
+
class="input"
|
|
3267
|
+
id="acc-new-password-confirm"
|
|
3268
|
+
type="password"
|
|
3269
|
+
required
|
|
3270
|
+
minlength="8"
|
|
3271
|
+
.value=${this.newPasswordConfirm}
|
|
3272
|
+
@input=${this.bind("newPasswordConfirm")}
|
|
3273
|
+
autocomplete="new-password"
|
|
3274
|
+
/>
|
|
3275
|
+
</div>
|
|
3276
|
+
${this.error("password")}
|
|
3277
|
+
</form>`,
|
|
3278
|
+
s`<button
|
|
3279
|
+
class="btn btn-primary btn-sm"
|
|
3280
|
+
type="submit"
|
|
3281
|
+
form="password-form"
|
|
3282
|
+
?disabled=${!!this.busy || !this.newPassword}
|
|
3283
|
+
>
|
|
3284
|
+
${this.spinner("password")} ${this.t("update")}
|
|
3285
|
+
</button>`
|
|
3286
|
+
)}
|
|
3287
|
+
${t ? this.renderMfaCard() : n}
|
|
3288
|
+
${t ? this.renderRecoveryCard() : n}
|
|
3289
|
+
</div>`;
|
|
3290
|
+
}
|
|
3291
|
+
renderMfaCard() {
|
|
3292
|
+
const e = this.user, t = this.factors?.totp ?? !1, i = this.authenticator ? new tt(o.getClient()).getQR(this.authenticator.uri, 400, 1).toString() : "";
|
|
3293
|
+
return this.card(
|
|
3294
|
+
this.t("twoFactor"),
|
|
3295
|
+
this.t("twoFactorDescription"),
|
|
3296
|
+
s`<div class="kv">
|
|
3297
|
+
<div class="toggle-row">
|
|
3298
|
+
<div class="row-main">
|
|
3299
|
+
<span class="row-title">${this.t("twoFactor")}</span>
|
|
3300
|
+
<span class="row-sub">${e.mfa ? this.t("enable") : this.t("disable")}d</span>
|
|
3301
|
+
</div>
|
|
3302
|
+
<button
|
|
3303
|
+
class="switch"
|
|
3304
|
+
role="switch"
|
|
3305
|
+
aria-checked=${e.mfa ? "true" : "false"}
|
|
3306
|
+
@click=${this.onToggleMfa}
|
|
3307
|
+
?disabled=${!!this.busy}
|
|
3308
|
+
aria-label=${this.t("twoFactor")}
|
|
3309
|
+
></button>
|
|
3310
|
+
</div>
|
|
3311
|
+
${this.error("mfa")}
|
|
3312
|
+
<div class="separator"></div>
|
|
3313
|
+
<div class="toggle-row">
|
|
3314
|
+
<div class="row-main">
|
|
3315
|
+
<span class="row-title"
|
|
3316
|
+
>${c.smartphone} ${this.t("authenticatorApp")}
|
|
3317
|
+
${t ? this.verifiedBadge(!0) : n}</span
|
|
3318
|
+
>
|
|
3319
|
+
</div>
|
|
3320
|
+
${t ? s`<button
|
|
3321
|
+
class="btn btn-outline btn-sm"
|
|
3322
|
+
@click=${this.onRemoveAuthenticator}
|
|
3323
|
+
?disabled=${!!this.busy}
|
|
3324
|
+
>
|
|
3325
|
+
${this.spinner("remove-authenticator")} ${this.t("remove")}
|
|
3326
|
+
</button>` : this.authenticator ? n : s`<button
|
|
3327
|
+
class="btn btn-outline btn-sm"
|
|
3328
|
+
@click=${this.onAddAuthenticator}
|
|
3329
|
+
?disabled=${!!this.busy}
|
|
3330
|
+
>
|
|
3331
|
+
${this.spinner("authenticator")} ${this.t("authenticatorAdd")}
|
|
3332
|
+
</button>`}
|
|
3333
|
+
</div>
|
|
3334
|
+
${this.error("authenticator")} ${this.error("remove-authenticator")}
|
|
3335
|
+
${this.authenticator ? s`<form class="form" @submit=${this.onVerifyAuthenticator} novalidate>
|
|
3336
|
+
<p class="hint">${this.t("authenticatorScan")}</p>
|
|
3337
|
+
<img class="qr" src=${i} alt="QR code" />
|
|
3338
|
+
<p class="hint center">
|
|
3339
|
+
${this.t("authenticatorManual")}:
|
|
3340
|
+
<span class="code">${this.authenticator.secret}</span>
|
|
3341
|
+
</p>
|
|
3342
|
+
<div class="field">
|
|
3343
|
+
<label class="label" for="acc-totp">${this.t("code")}</label>
|
|
3344
|
+
<input
|
|
3345
|
+
class="input input-otp"
|
|
3346
|
+
id="acc-totp"
|
|
3347
|
+
inputmode="numeric"
|
|
3348
|
+
autocomplete="one-time-code"
|
|
3349
|
+
required
|
|
3350
|
+
.value=${this.authenticatorCode}
|
|
3351
|
+
@input=${this.bind("authenticatorCode")}
|
|
3352
|
+
/>
|
|
3353
|
+
</div>
|
|
3354
|
+
${this.error("authenticator-code")}
|
|
3355
|
+
<div class="inline">
|
|
3356
|
+
<button class="btn btn-primary btn-sm" type="submit" ?disabled=${!!this.busy}>
|
|
3357
|
+
${this.spinner("authenticator-code")} ${this.t("authenticatorVerify")}
|
|
3358
|
+
</button>
|
|
3359
|
+
<button
|
|
3360
|
+
class="btn btn-ghost btn-sm"
|
|
3361
|
+
type="button"
|
|
3362
|
+
@click=${() => this.authenticator = null}
|
|
3363
|
+
>
|
|
3364
|
+
${this.t("cancel")}
|
|
3365
|
+
</button>
|
|
3366
|
+
</div>
|
|
3367
|
+
</form>` : n}
|
|
3368
|
+
</div>`
|
|
3369
|
+
);
|
|
3370
|
+
}
|
|
3371
|
+
renderRecoveryCard() {
|
|
3372
|
+
const e = this.factors?.recoveryCode ?? !1;
|
|
3373
|
+
return this.card(
|
|
3374
|
+
this.t("recoveryCodes"),
|
|
3375
|
+
this.t("recoveryCodesDescription"),
|
|
3376
|
+
s`<div class="kv">
|
|
3377
|
+
${this.recoveryCodes ? s`<div class="alert alert-warning">
|
|
3378
|
+
${c.alert}
|
|
3379
|
+
<div class="alert-body">${this.t("recoveryCodesWarning")}</div>
|
|
3380
|
+
</div>
|
|
3381
|
+
<div class="codes">
|
|
3382
|
+
${this.recoveryCodes.map((t) => s`<span class="code">${t}</span>`)}
|
|
3383
|
+
</div>
|
|
3384
|
+
<div class="inline">
|
|
3385
|
+
<button class="btn btn-outline btn-sm" @click=${this.onCopyCodes}>
|
|
3386
|
+
${this.copied ? c.check : c.copy}
|
|
3387
|
+
${this.copied ? this.t("copied") : this.t("copy")}
|
|
3388
|
+
</button>
|
|
3389
|
+
<button class="btn btn-ghost btn-sm" @click=${() => this.recoveryCodes = null}>
|
|
3390
|
+
${this.t("done")}
|
|
3391
|
+
</button>
|
|
3392
|
+
</div>` : s`<div class="inline">
|
|
3393
|
+
<button
|
|
3394
|
+
class="btn btn-outline btn-sm"
|
|
3395
|
+
@click=${this.onRecoveryCodes}
|
|
3396
|
+
?disabled=${!!this.busy}
|
|
3397
|
+
>
|
|
3398
|
+
${this.spinner("recovery")} ${c.key}
|
|
3399
|
+
${e ? this.t("recoveryCodes") : this.t("generateRecoveryCodes")}
|
|
3400
|
+
</button>
|
|
3401
|
+
${e ? s`<button class="btn btn-ghost btn-sm" @click=${this.onRegenerateRecoveryCodes} ?disabled=${!!this.busy}>${c.refresh} ${this.t("regenerateRecoveryCodes")}</button>` : n}
|
|
3402
|
+
</div>`}
|
|
3403
|
+
${this.error("recovery")}
|
|
3404
|
+
</div>`
|
|
3405
|
+
);
|
|
3406
|
+
}
|
|
3407
|
+
/** Inline MFA challenge shown when Appwrite demands a recent factor for a protected action. */
|
|
3408
|
+
renderStepUp() {
|
|
3409
|
+
const e = this.stepUp, t = this.factors, i = [
|
|
3410
|
+
{
|
|
3411
|
+
factor: "totp",
|
|
3412
|
+
icon: c.smartphone,
|
|
3413
|
+
label: this.t("mfaUseAuthenticator"),
|
|
3414
|
+
available: t?.totp ?? !0
|
|
3415
|
+
},
|
|
3416
|
+
{
|
|
3417
|
+
factor: "email",
|
|
3418
|
+
icon: c.mail,
|
|
3419
|
+
label: this.t("mfaUseEmail"),
|
|
3420
|
+
available: t?.email ?? !0
|
|
3421
|
+
},
|
|
3422
|
+
{
|
|
3423
|
+
factor: "phone",
|
|
3424
|
+
icon: c.phone,
|
|
3425
|
+
label: this.t("mfaUsePhone"),
|
|
3426
|
+
available: t?.phone ?? !0
|
|
3427
|
+
},
|
|
3428
|
+
{
|
|
3429
|
+
factor: "recoverycode",
|
|
3430
|
+
icon: c.key,
|
|
3431
|
+
label: this.t("mfaUseRecoveryCode"),
|
|
3432
|
+
available: t?.recoveryCode ?? !0
|
|
3433
|
+
}
|
|
3434
|
+
];
|
|
3435
|
+
return this.card(
|
|
3436
|
+
this.t("mfaTitle"),
|
|
3437
|
+
this.t("errorChallengeRequired"),
|
|
3438
|
+
s`<div class="kv">
|
|
3439
|
+
${e.challenge ? s`<form class="form" @submit=${this.onStepUpVerify} novalidate>
|
|
3440
|
+
<div class="field">
|
|
3441
|
+
<label class="label" for="acc-stepup"
|
|
3442
|
+
>${e.challenge.factor === "recoverycode" ? this.t("recoveryCode") : this.t("code")}</label
|
|
3443
|
+
>
|
|
3444
|
+
<input
|
|
3445
|
+
class="input ${e.challenge.factor === "recoverycode" ? "mono" : "input-otp"}"
|
|
3446
|
+
id="acc-stepup"
|
|
3447
|
+
autocomplete="one-time-code"
|
|
3448
|
+
required
|
|
3449
|
+
.value=${this.stepUpCode}
|
|
3450
|
+
@input=${this.bind("stepUpCode")}
|
|
3451
|
+
/>
|
|
3452
|
+
</div>
|
|
3453
|
+
<button class="btn btn-primary btn-sm" type="submit" ?disabled=${!!this.busy}>
|
|
3454
|
+
${this.spinner("stepup-code")} ${this.t("verifyCode")}
|
|
3455
|
+
</button>
|
|
3456
|
+
</form>` : s`<div class="stack-sm">
|
|
3457
|
+
${i.filter((r) => r.available).map(
|
|
3458
|
+
(r) => s`<button
|
|
3459
|
+
type="button"
|
|
3460
|
+
class="choice"
|
|
3461
|
+
@click=${() => this.onStepUpFactor(r.factor)}
|
|
3462
|
+
?disabled=${!!this.busy}
|
|
3463
|
+
>
|
|
3464
|
+
${r.icon}<span class="choice-title">${r.label}</span>
|
|
3465
|
+
</button>`
|
|
3466
|
+
)}
|
|
3467
|
+
</div>`}
|
|
3468
|
+
${this.error("stepup")} ${this.error("stepup-code")}
|
|
3469
|
+
</div>`,
|
|
3470
|
+
s`<button class="btn btn-ghost btn-sm" @click=${() => this.stepUp = null}>
|
|
3471
|
+
${this.t("cancel")}
|
|
3472
|
+
</button>`
|
|
3473
|
+
);
|
|
3474
|
+
}
|
|
3475
|
+
// ── Sessions ──
|
|
3476
|
+
deviceIcon(e) {
|
|
3477
|
+
const t = (e.clientType || e.deviceName || "").toLowerCase();
|
|
3478
|
+
return t.includes("smartphone") || t.includes("phone") || t.includes("tablet") ? c.smartphone : t.includes("browser") || t.includes("desktop") ? c.monitor : c.globe;
|
|
3479
|
+
}
|
|
3480
|
+
renderSessions() {
|
|
3481
|
+
const e = this.sessions;
|
|
3482
|
+
return s`<div class="section">
|
|
3483
|
+
${this.card(
|
|
3484
|
+
this.t("sessions"),
|
|
3485
|
+
void 0,
|
|
3486
|
+
s`${this.error("sessions")}
|
|
3487
|
+
${e === null ? s`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? s`<div class="empty">${this.t("noActivity")}</div>` : e.map(
|
|
3488
|
+
(t) => s`<div class="row">
|
|
3489
|
+
<div class="inline">
|
|
3490
|
+
<span class="device">${this.deviceIcon(t)}</span>
|
|
3491
|
+
<div class="row-main">
|
|
3492
|
+
<span class="row-title">
|
|
3493
|
+
${t.clientName || t.provider}
|
|
3494
|
+
${t.clientVersion ? s`<span class="muted small">${t.clientVersion}</span>` : n}
|
|
3495
|
+
${t.current ? s`<span class="badge badge-info">${this.t("currentSession")}</span>` : n}
|
|
3496
|
+
</span>
|
|
3497
|
+
<span class="row-sub"
|
|
3498
|
+
>${[t.osName, t.countryName || t.countryCode, t.ip].filter(Boolean).join(" · ")}</span
|
|
3499
|
+
>
|
|
3500
|
+
</div>
|
|
3501
|
+
</div>
|
|
3502
|
+
<div class="row-actions">
|
|
3503
|
+
${this.busy === `session-${t.$id}` ? s`<span class="spinner"></span>` : n}
|
|
3504
|
+
<button
|
|
3505
|
+
class="btn btn-ghost btn-sm"
|
|
3506
|
+
@click=${() => this.onDeleteSession(t.$id)}
|
|
3507
|
+
?disabled=${!!this.busy}
|
|
3508
|
+
aria-label=${this.t("signOutSession")}
|
|
3509
|
+
>
|
|
3510
|
+
${c.logOut}
|
|
3511
|
+
</button>
|
|
3512
|
+
</div>
|
|
3513
|
+
</div>`
|
|
3514
|
+
)}`
|
|
3515
|
+
)}
|
|
3516
|
+
${this.card(
|
|
3517
|
+
this.t("signOutAllSessions"),
|
|
3518
|
+
this.t("signOutAllSessionsDescription"),
|
|
3519
|
+
s`${this.error("sessions-all")}
|
|
3520
|
+
<button
|
|
3521
|
+
class="btn btn-outline btn-sm warn"
|
|
3522
|
+
@click=${this.onSignOutAll}
|
|
3523
|
+
?disabled=${!!this.busy}
|
|
3524
|
+
>
|
|
3525
|
+
${this.spinner("sessions-all")} ${c.logOut} ${this.t("signOutAllSessions")}
|
|
3526
|
+
</button>`,
|
|
3527
|
+
void 0,
|
|
3528
|
+
!0
|
|
3529
|
+
)}
|
|
3530
|
+
</div>`;
|
|
3531
|
+
}
|
|
3532
|
+
// ── Connections ──
|
|
3533
|
+
renderConnections() {
|
|
3534
|
+
const e = this.identities, t = this.config?.methods?.oauth ?? [];
|
|
3535
|
+
return s`<div class="section">
|
|
3536
|
+
${this.card(
|
|
3537
|
+
this.t("connections"),
|
|
3538
|
+
void 0,
|
|
3539
|
+
s`${this.error("identities")}
|
|
3540
|
+
${e === null ? s`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? s`<div class="empty">${this.t("noConnections")}</div>` : e.map(
|
|
3541
|
+
(i) => s`<div class="row">
|
|
3542
|
+
<div class="inline">
|
|
3543
|
+
<span class="device">${L(i.provider)}</span>
|
|
3544
|
+
<div class="row-main">
|
|
3545
|
+
<span class="row-title">${E(i.provider)}</span>
|
|
3546
|
+
<span class="row-sub">${i.providerEmail || i.providerUid}</span>
|
|
3547
|
+
</div>
|
|
3548
|
+
</div>
|
|
3549
|
+
<div class="row-actions">
|
|
3550
|
+
<button
|
|
3551
|
+
class="btn btn-ghost btn-sm"
|
|
3552
|
+
@click=${() => this.onDeleteIdentity(i.$id)}
|
|
3553
|
+
?disabled=${!!this.busy}
|
|
3554
|
+
>
|
|
3555
|
+
${this.busy === `identity-${i.$id}` ? s`<span class="spinner"></span>` : n}
|
|
3556
|
+
${this.t("disconnect")}
|
|
3557
|
+
</button>
|
|
3558
|
+
</div>
|
|
3559
|
+
</div>`
|
|
3560
|
+
)}`,
|
|
3561
|
+
t.length > 0 ? s`${t.filter((i) => !(e ?? []).some((r) => r.provider === i)).map(
|
|
3562
|
+
(i) => s`<button
|
|
3563
|
+
class="btn btn-outline btn-sm"
|
|
3564
|
+
@click=${() => o.signInWithOAuth(i)}
|
|
3565
|
+
>
|
|
3566
|
+
${L(i)} ${E(i)}
|
|
3567
|
+
</button>`
|
|
3568
|
+
)}` : void 0
|
|
3569
|
+
)}
|
|
3570
|
+
</div>`;
|
|
3571
|
+
}
|
|
3572
|
+
// ── Activity ──
|
|
3573
|
+
renderActivity() {
|
|
3574
|
+
const e = this.logs;
|
|
3575
|
+
return s`<div class="section">
|
|
3576
|
+
${this.card(
|
|
3577
|
+
this.t("activity"),
|
|
3578
|
+
void 0,
|
|
3579
|
+
s`${e === null ? s`<div class="empty"><span class="spinner"></span></div>` : e.length === 0 ? s`<div class="empty">${this.t("noActivity")}</div>` : e.map(
|
|
3580
|
+
(t) => s`<div class="row">
|
|
3581
|
+
<div class="row-main">
|
|
3582
|
+
<span class="row-title">${t.event}</span>
|
|
3583
|
+
<span class="row-sub"
|
|
3584
|
+
>${[t.clientName, t.osName, t.countryName || t.countryCode, t.ip].filter(Boolean).join(" · ")}</span
|
|
3585
|
+
>
|
|
3586
|
+
</div>
|
|
3587
|
+
<span class="log-time">${new Date(t.time).toLocaleString()}</span>
|
|
3588
|
+
</div>`
|
|
3589
|
+
)}`
|
|
3590
|
+
)}
|
|
3591
|
+
</div>`;
|
|
3592
|
+
}
|
|
3593
|
+
};
|
|
3594
|
+
p.styles = [
|
|
3595
|
+
...x.styles,
|
|
3596
|
+
A`
|
|
3597
|
+
:host {
|
|
3598
|
+
display: block;
|
|
3599
|
+
width: 100%;
|
|
3600
|
+
max-width: 560px;
|
|
3601
|
+
}
|
|
3602
|
+
.panel {
|
|
3603
|
+
background: var(--authui-card);
|
|
3604
|
+
color: var(--authui-card-foreground);
|
|
3605
|
+
border: 1px solid var(--authui-border);
|
|
3606
|
+
border-radius: var(--authui-radius-xl);
|
|
3607
|
+
padding: 24px;
|
|
3608
|
+
display: flex;
|
|
3609
|
+
flex-direction: column;
|
|
3610
|
+
gap: 20px;
|
|
3611
|
+
box-shadow: var(--authui-shadow-lg);
|
|
3612
|
+
}
|
|
3613
|
+
.panel.embedded {
|
|
3614
|
+
border: 0;
|
|
3615
|
+
box-shadow: none;
|
|
3616
|
+
padding: 0;
|
|
3617
|
+
background: transparent;
|
|
3618
|
+
}
|
|
3619
|
+
.identity {
|
|
3620
|
+
display: flex;
|
|
3621
|
+
align-items: center;
|
|
3622
|
+
gap: 12px;
|
|
3623
|
+
}
|
|
3624
|
+
.identity .avatar {
|
|
3625
|
+
width: 44px;
|
|
3626
|
+
height: 44px;
|
|
3627
|
+
font-size: 16px;
|
|
3628
|
+
}
|
|
3629
|
+
.tabs {
|
|
3630
|
+
width: 100%;
|
|
3631
|
+
}
|
|
3632
|
+
.section {
|
|
3633
|
+
display: flex;
|
|
3634
|
+
flex-direction: column;
|
|
3635
|
+
gap: 16px;
|
|
3636
|
+
}
|
|
3637
|
+
.kv {
|
|
3638
|
+
display: flex;
|
|
3639
|
+
flex-direction: column;
|
|
3640
|
+
gap: 12px;
|
|
3641
|
+
}
|
|
3642
|
+
.toggle-row {
|
|
3643
|
+
display: flex;
|
|
3644
|
+
align-items: center;
|
|
3645
|
+
justify-content: space-between;
|
|
3646
|
+
gap: 16px;
|
|
3647
|
+
}
|
|
3648
|
+
.device {
|
|
3649
|
+
width: 36px;
|
|
3650
|
+
height: 36px;
|
|
3651
|
+
border-radius: var(--authui-radius-md);
|
|
3652
|
+
background: var(--authui-muted);
|
|
3653
|
+
color: var(--authui-muted-foreground);
|
|
3654
|
+
display: inline-flex;
|
|
3655
|
+
align-items: center;
|
|
3656
|
+
justify-content: center;
|
|
3657
|
+
flex-shrink: 0;
|
|
3658
|
+
}
|
|
3659
|
+
.device svg {
|
|
3660
|
+
width: 18px;
|
|
3661
|
+
height: 18px;
|
|
3662
|
+
}
|
|
3663
|
+
.log-time {
|
|
3664
|
+
font-size: 12px;
|
|
3665
|
+
color: var(--authui-muted-foreground);
|
|
3666
|
+
white-space: nowrap;
|
|
3667
|
+
}
|
|
3668
|
+
.warn {
|
|
3669
|
+
color: var(--authui-destructive-foreground);
|
|
3670
|
+
}
|
|
3671
|
+
`
|
|
3672
|
+
];
|
|
3673
|
+
m([
|
|
3674
|
+
g({ type: Boolean })
|
|
3675
|
+
], p.prototype, "embedded", 2);
|
|
3676
|
+
m([
|
|
3677
|
+
g({ type: String })
|
|
3678
|
+
], p.prototype, "tab", 2);
|
|
3679
|
+
m([
|
|
3680
|
+
d()
|
|
3681
|
+
], p.prototype, "active", 2);
|
|
3682
|
+
m([
|
|
3683
|
+
d()
|
|
3684
|
+
], p.prototype, "busy", 2);
|
|
3685
|
+
m([
|
|
3686
|
+
d()
|
|
3687
|
+
], p.prototype, "notice", 2);
|
|
3688
|
+
m([
|
|
3689
|
+
d()
|
|
3690
|
+
], p.prototype, "errors", 2);
|
|
3691
|
+
m([
|
|
3692
|
+
d()
|
|
3693
|
+
], p.prototype, "nameInput", 2);
|
|
3694
|
+
m([
|
|
3695
|
+
d()
|
|
3696
|
+
], p.prototype, "emailInput", 2);
|
|
3697
|
+
m([
|
|
3698
|
+
d()
|
|
3699
|
+
], p.prototype, "emailPassword", 2);
|
|
3700
|
+
m([
|
|
3701
|
+
d()
|
|
3702
|
+
], p.prototype, "phoneInput", 2);
|
|
3703
|
+
m([
|
|
3704
|
+
d()
|
|
3705
|
+
], p.prototype, "phonePassword", 2);
|
|
3706
|
+
m([
|
|
3707
|
+
d()
|
|
3708
|
+
], p.prototype, "phoneCode", 2);
|
|
3709
|
+
m([
|
|
3710
|
+
d()
|
|
3711
|
+
], p.prototype, "phoneCodeSent", 2);
|
|
3712
|
+
m([
|
|
3713
|
+
d()
|
|
3714
|
+
], p.prototype, "guestName", 2);
|
|
3715
|
+
m([
|
|
3716
|
+
d()
|
|
3717
|
+
], p.prototype, "oldPassword", 2);
|
|
3718
|
+
m([
|
|
3719
|
+
d()
|
|
3720
|
+
], p.prototype, "newPassword", 2);
|
|
3721
|
+
m([
|
|
3722
|
+
d()
|
|
3723
|
+
], p.prototype, "newPasswordConfirm", 2);
|
|
3724
|
+
m([
|
|
3725
|
+
d()
|
|
3726
|
+
], p.prototype, "authenticator", 2);
|
|
3727
|
+
m([
|
|
3728
|
+
d()
|
|
3729
|
+
], p.prototype, "authenticatorCode", 2);
|
|
3730
|
+
m([
|
|
3731
|
+
d()
|
|
3732
|
+
], p.prototype, "factors", 2);
|
|
3733
|
+
m([
|
|
3734
|
+
d()
|
|
3735
|
+
], p.prototype, "recoveryCodes", 2);
|
|
3736
|
+
m([
|
|
3737
|
+
d()
|
|
3738
|
+
], p.prototype, "stepUp", 2);
|
|
3739
|
+
m([
|
|
3740
|
+
d()
|
|
3741
|
+
], p.prototype, "stepUpCode", 2);
|
|
3742
|
+
m([
|
|
3743
|
+
d()
|
|
3744
|
+
], p.prototype, "copied", 2);
|
|
3745
|
+
m([
|
|
3746
|
+
d()
|
|
3747
|
+
], p.prototype, "sessions", 2);
|
|
3748
|
+
m([
|
|
3749
|
+
d()
|
|
3750
|
+
], p.prototype, "identities", 2);
|
|
3751
|
+
m([
|
|
3752
|
+
d()
|
|
3753
|
+
], p.prototype, "logs", 2);
|
|
3754
|
+
m([
|
|
3755
|
+
d()
|
|
3756
|
+
], p.prototype, "logsSupported", 2);
|
|
3757
|
+
m([
|
|
3758
|
+
d()
|
|
3759
|
+
], p.prototype, "confirmDelete", 2);
|
|
3760
|
+
p = m([
|
|
3761
|
+
S("authui-account")
|
|
3762
|
+
], p);
|
|
3763
|
+
var wt = Object.defineProperty, $t = Object.getOwnPropertyDescriptor, U = (e, t, i, r) => {
|
|
3764
|
+
for (var a = r > 1 ? void 0 : r ? $t(t, i) : t, u = e.length - 1, h; u >= 0; u--)
|
|
3765
|
+
(h = e[u]) && (a = (r ? h(t, i, a) : h(a)) || a);
|
|
3766
|
+
return r && a && wt(t, i, a), a;
|
|
3767
|
+
};
|
|
3768
|
+
let P = class extends x {
|
|
3769
|
+
constructor() {
|
|
3770
|
+
super(...arguments), this.open = !1, this.view = "sign-in", this.closeOnSuccess = !0, this.handledPending = null, this.onOpenEvent = (e) => {
|
|
3771
|
+
const t = e.detail ?? {};
|
|
3772
|
+
this.show(t.view);
|
|
3773
|
+
}, this.onCloseEvent = () => this.hide(), this.onSuccess = () => {
|
|
3774
|
+
this.fire("authui-signed-in", this.auth.user), this.closeOnSuccess && !this.config?.successUrl && this.hide();
|
|
3775
|
+
}, this.onInnerOpen = (e) => {
|
|
3776
|
+
const t = e.detail?.view;
|
|
3777
|
+
t && (this.view = t);
|
|
3778
|
+
}, this.onBackdrop = (e) => {
|
|
3779
|
+
e.target === this.dialog && this.hide();
|
|
3780
|
+
};
|
|
3781
|
+
}
|
|
3782
|
+
connectedCallback() {
|
|
3783
|
+
super.connectedCallback(), window.addEventListener("authui:open", this.onOpenEvent), window.addEventListener("authui:close", this.onCloseEvent);
|
|
3784
|
+
}
|
|
3785
|
+
disconnectedCallback() {
|
|
3786
|
+
super.disconnectedCallback(), window.removeEventListener("authui:open", this.onOpenEvent), window.removeEventListener("authui:close", this.onCloseEvent);
|
|
3787
|
+
}
|
|
3788
|
+
show(e) {
|
|
3789
|
+
e ? this.view = e : this.auth.status === "signed-in" && (this.view = "account"), this.open = !0;
|
|
3790
|
+
}
|
|
3791
|
+
hide() {
|
|
3792
|
+
this.open = !1;
|
|
3793
|
+
}
|
|
3794
|
+
updated(e) {
|
|
3795
|
+
if (e.has("open") && this.dialog && (this.open && !this.dialog.open && this.dialog.showModal(), !this.open && this.dialog.open && this.dialog.close()), e.has("auth")) {
|
|
3796
|
+
const t = this.auth.pending;
|
|
3797
|
+
t && t !== this.handledPending && t.type !== "notice" && (this.handledPending = t, this.view = "sign-in", this.open = !0), t?.type === "notice" && t !== this.handledPending && (this.handledPending = t, this.open = !0);
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
render() {
|
|
3801
|
+
const e = this.view === "account";
|
|
3802
|
+
return s`
|
|
3803
|
+
<dialog
|
|
3804
|
+
class=${e ? "wide" : ""}
|
|
3805
|
+
aria-labelledby="authui-title"
|
|
3806
|
+
@close=${() => this.open = !1}
|
|
3807
|
+
@cancel=${(t) => {
|
|
3808
|
+
t.preventDefault(), this.hide();
|
|
3809
|
+
}}
|
|
3810
|
+
@click=${this.onBackdrop}
|
|
3811
|
+
@authui-open=${this.onInnerOpen}
|
|
3812
|
+
>
|
|
3813
|
+
<div class="body">
|
|
3814
|
+
<button
|
|
3815
|
+
class="btn btn-ghost btn-icon close"
|
|
3816
|
+
@click=${this.hide}
|
|
3817
|
+
aria-label=${this.t("close")}
|
|
3818
|
+
>
|
|
3819
|
+
${c.x}
|
|
3820
|
+
</button>
|
|
3821
|
+
${this.open ? e ? s`<authui-account embedded></authui-account>` : s`<authui-sign-in
|
|
3822
|
+
embedded
|
|
3823
|
+
.view=${this.view}
|
|
3824
|
+
@authui-success=${this.onSuccess}
|
|
3825
|
+
></authui-sign-in>` : n}
|
|
3826
|
+
</div>
|
|
3827
|
+
</dialog>
|
|
3828
|
+
`;
|
|
3829
|
+
}
|
|
3830
|
+
};
|
|
3831
|
+
P.styles = [
|
|
3832
|
+
...x.styles,
|
|
3833
|
+
A`
|
|
3834
|
+
:host {
|
|
3835
|
+
display: contents;
|
|
3836
|
+
}
|
|
3837
|
+
dialog {
|
|
3838
|
+
border: 1px solid var(--authui-border);
|
|
3839
|
+
border-radius: var(--authui-radius-lg);
|
|
3840
|
+
background: var(--authui-background);
|
|
3841
|
+
color: var(--authui-foreground);
|
|
3842
|
+
padding: 0;
|
|
3843
|
+
width: calc(100% - 2rem);
|
|
3844
|
+
max-width: 440px;
|
|
3845
|
+
max-height: calc(100dvh - 2rem);
|
|
3846
|
+
box-shadow: var(--authui-shadow-lg);
|
|
3847
|
+
overflow: hidden;
|
|
3848
|
+
z-index: var(--authui-z);
|
|
3849
|
+
}
|
|
3850
|
+
dialog.wide {
|
|
3851
|
+
max-width: 600px;
|
|
3852
|
+
}
|
|
3853
|
+
dialog::backdrop {
|
|
3854
|
+
background: var(--authui-overlay);
|
|
3855
|
+
backdrop-filter: blur(4px);
|
|
3856
|
+
}
|
|
3857
|
+
dialog[open] {
|
|
3858
|
+
animation: authui-in 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
3859
|
+
}
|
|
3860
|
+
@keyframes authui-in {
|
|
3861
|
+
from {
|
|
3862
|
+
opacity: 0;
|
|
3863
|
+
transform: scale(0.96);
|
|
3864
|
+
}
|
|
3865
|
+
to {
|
|
3866
|
+
opacity: 1;
|
|
3867
|
+
transform: none;
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
.body {
|
|
3871
|
+
padding: 24px;
|
|
3872
|
+
max-height: calc(100dvh - 2rem);
|
|
3873
|
+
overflow-y: auto;
|
|
3874
|
+
}
|
|
3875
|
+
.close {
|
|
3876
|
+
position: absolute;
|
|
3877
|
+
top: 12px;
|
|
3878
|
+
inset-inline-end: 12px;
|
|
3879
|
+
width: 32px;
|
|
3880
|
+
height: 32px;
|
|
3881
|
+
border-radius: var(--authui-radius-sm);
|
|
3882
|
+
opacity: 0.7;
|
|
3883
|
+
}
|
|
3884
|
+
.close:hover {
|
|
3885
|
+
opacity: 1;
|
|
3886
|
+
}
|
|
3887
|
+
authui-sign-in,
|
|
3888
|
+
authui-account {
|
|
3889
|
+
max-width: none;
|
|
3890
|
+
}
|
|
3891
|
+
`
|
|
3892
|
+
];
|
|
3893
|
+
U([
|
|
3894
|
+
g({ type: Boolean, reflect: !0 })
|
|
3895
|
+
], P.prototype, "open", 2);
|
|
3896
|
+
U([
|
|
3897
|
+
g({ type: String })
|
|
3898
|
+
], P.prototype, "view", 2);
|
|
3899
|
+
U([
|
|
3900
|
+
g({ type: Boolean, attribute: "close-on-success" })
|
|
3901
|
+
], P.prototype, "closeOnSuccess", 2);
|
|
3902
|
+
U([
|
|
3903
|
+
d()
|
|
3904
|
+
], P.prototype, "handledPending", 2);
|
|
3905
|
+
U([
|
|
3906
|
+
X("dialog")
|
|
3907
|
+
], P.prototype, "dialog", 2);
|
|
3908
|
+
P = U([
|
|
3909
|
+
S("authui-modal")
|
|
3910
|
+
], P);
|
|
3911
|
+
function R(e) {
|
|
3912
|
+
typeof document > "u" || (document.querySelector("authui-modal") || document.body.appendChild(document.createElement("authui-modal")), queueMicrotask(() => {
|
|
3913
|
+
window.dispatchEvent(new CustomEvent("authui:open", { detail: { view: e } }));
|
|
3914
|
+
}));
|
|
3915
|
+
}
|
|
3916
|
+
function Ut() {
|
|
3917
|
+
typeof window > "u" || window.dispatchEvent(new CustomEvent("authui:close"));
|
|
3918
|
+
}
|
|
3919
|
+
var xt = Object.defineProperty, kt = Object.getOwnPropertyDescriptor, O = (e, t, i, r) => {
|
|
3920
|
+
for (var a = r > 1 ? void 0 : r ? kt(t, i) : t, u = e.length - 1, h; u >= 0; u--)
|
|
3921
|
+
(h = e[u]) && (a = (r ? h(t, i, a) : h(a)) || a);
|
|
3922
|
+
return r && a && xt(t, i, a), a;
|
|
3923
|
+
};
|
|
3924
|
+
let M = class extends x {
|
|
3925
|
+
constructor() {
|
|
3926
|
+
super(...arguments), this.view = "sign-in", this.variant = "primary", this.size = "md";
|
|
3927
|
+
}
|
|
3928
|
+
render() {
|
|
3929
|
+
const e = this.size === "md" ? "" : `btn-${this.size}`;
|
|
3930
|
+
return s`<button
|
|
3931
|
+
class="btn btn-${this.variant} ${e}"
|
|
3932
|
+
@click=${() => R(this.view)}
|
|
3933
|
+
part="button"
|
|
3934
|
+
>
|
|
3935
|
+
<slot
|
|
3936
|
+
>${this.view === "sign-up" ? this.t("signUp") : this.view === "account" ? this.t("manageAccount") : this.t("signIn")}</slot
|
|
3937
|
+
>
|
|
3938
|
+
</button>`;
|
|
3939
|
+
}
|
|
3940
|
+
};
|
|
3941
|
+
M.styles = [
|
|
3942
|
+
...x.styles,
|
|
3943
|
+
A`
|
|
3944
|
+
:host {
|
|
3945
|
+
display: inline-block;
|
|
3946
|
+
}
|
|
3947
|
+
.btn {
|
|
3948
|
+
width: 100%;
|
|
3949
|
+
}
|
|
3950
|
+
`
|
|
3951
|
+
];
|
|
3952
|
+
O([
|
|
3953
|
+
g({ type: String })
|
|
3954
|
+
], M.prototype, "view", 2);
|
|
3955
|
+
O([
|
|
3956
|
+
g({ type: String })
|
|
3957
|
+
], M.prototype, "variant", 2);
|
|
3958
|
+
O([
|
|
3959
|
+
g({ type: String })
|
|
3960
|
+
], M.prototype, "size", 2);
|
|
3961
|
+
M = O([
|
|
3962
|
+
S("authui-button")
|
|
3963
|
+
], M);
|
|
3964
|
+
var Ct = Object.defineProperty, Pt = Object.getOwnPropertyDescriptor, q = (e, t, i, r) => {
|
|
3965
|
+
for (var a = r > 1 ? void 0 : r ? Pt(t, i) : t, u = e.length - 1, h; u >= 0; u--)
|
|
3966
|
+
(h = e[u]) && (a = (r ? h(t, i, a) : h(a)) || a);
|
|
3967
|
+
return r && a && Ct(t, i, a), a;
|
|
3968
|
+
};
|
|
3969
|
+
let I = class extends x {
|
|
3970
|
+
constructor() {
|
|
3971
|
+
super(...arguments), this.src = "", this.menuOpen = !1, this.onDocumentClick = (e) => {
|
|
3972
|
+
e.composedPath().includes(this) || (this.menuOpen = !1);
|
|
3973
|
+
}, this.onKeydown = (e) => {
|
|
3974
|
+
e.key === "Escape" && (this.menuOpen = !1);
|
|
3975
|
+
};
|
|
3976
|
+
}
|
|
3977
|
+
connectedCallback() {
|
|
3978
|
+
super.connectedCallback(), document.addEventListener("click", this.onDocumentClick, !0), document.addEventListener("keydown", this.onKeydown);
|
|
3979
|
+
}
|
|
3980
|
+
disconnectedCallback() {
|
|
3981
|
+
super.disconnectedCallback(), document.removeEventListener("click", this.onDocumentClick, !0), document.removeEventListener("keydown", this.onKeydown);
|
|
3982
|
+
}
|
|
3983
|
+
render() {
|
|
3984
|
+
const { status: e, user: t } = this.auth;
|
|
3985
|
+
if (e === "loading")
|
|
3986
|
+
return s`<span class="avatar"><span class="spinner"></span></span>`;
|
|
3987
|
+
if (e !== "signed-in" || !t)
|
|
3988
|
+
return s`<button class="btn btn-primary btn-sm" @click=${() => R("sign-in")}>
|
|
3989
|
+
<slot>${this.t("signIn")}</slot>
|
|
3990
|
+
</button>`;
|
|
3991
|
+
const i = t.name || t.email || t.phone || this.t("guestAccount");
|
|
3992
|
+
return s`
|
|
3993
|
+
<button
|
|
3994
|
+
class="trigger"
|
|
3995
|
+
aria-haspopup="menu"
|
|
3996
|
+
aria-expanded=${this.menuOpen ? "true" : "false"}
|
|
3997
|
+
@click=${() => this.menuOpen = !this.menuOpen}
|
|
3998
|
+
aria-label=${i}
|
|
3999
|
+
>
|
|
4000
|
+
<span class="avatar"
|
|
4001
|
+
>${this.src ? s`<img src=${this.src} alt="" />` : i[0] ?? "?"}</span
|
|
4002
|
+
>
|
|
4003
|
+
</button>
|
|
4004
|
+
${this.menuOpen ? s`<div class="menu" role="menu">
|
|
4005
|
+
<div class="menu-header">
|
|
4006
|
+
<span class="row-title">${i}</span>
|
|
4007
|
+
${t.email && t.name ? s`<span class="row-sub">${t.email}</span>` : n}
|
|
4008
|
+
</div>
|
|
4009
|
+
<button
|
|
4010
|
+
class="menu-item"
|
|
4011
|
+
role="menuitem"
|
|
4012
|
+
@click=${() => {
|
|
4013
|
+
this.menuOpen = !1, R("account");
|
|
4014
|
+
}}
|
|
4015
|
+
>
|
|
4016
|
+
${c.settings} ${this.t("manageAccount")}
|
|
4017
|
+
</button>
|
|
4018
|
+
<button
|
|
4019
|
+
class="menu-item"
|
|
4020
|
+
role="menuitem"
|
|
4021
|
+
@click=${() => {
|
|
4022
|
+
this.menuOpen = !1, o.signOut();
|
|
4023
|
+
}}
|
|
4024
|
+
>
|
|
4025
|
+
${c.logOut} ${this.t("signOut")}
|
|
4026
|
+
</button>
|
|
4027
|
+
</div>` : n}
|
|
4028
|
+
`;
|
|
4029
|
+
}
|
|
4030
|
+
};
|
|
4031
|
+
I.styles = [
|
|
4032
|
+
...x.styles,
|
|
4033
|
+
A`
|
|
4034
|
+
:host {
|
|
4035
|
+
display: inline-block;
|
|
4036
|
+
position: relative;
|
|
4037
|
+
}
|
|
4038
|
+
.trigger {
|
|
4039
|
+
border: 1px solid transparent;
|
|
4040
|
+
background: transparent;
|
|
4041
|
+
padding: 2px;
|
|
4042
|
+
border-radius: 999px;
|
|
4043
|
+
cursor: pointer;
|
|
4044
|
+
display: inline-flex;
|
|
4045
|
+
transition: border-color 150ms;
|
|
4046
|
+
}
|
|
4047
|
+
.trigger:hover,
|
|
4048
|
+
.trigger[aria-expanded="true"] {
|
|
4049
|
+
border-color: var(--authui-border);
|
|
4050
|
+
}
|
|
4051
|
+
.trigger:focus-visible {
|
|
4052
|
+
outline: none;
|
|
4053
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--authui-ring) 50%, transparent);
|
|
4054
|
+
}
|
|
4055
|
+
.menu {
|
|
4056
|
+
position: absolute;
|
|
4057
|
+
top: calc(100% + 6px);
|
|
4058
|
+
inset-inline-end: 0;
|
|
4059
|
+
min-width: 220px;
|
|
4060
|
+
background: var(--authui-popover);
|
|
4061
|
+
color: var(--authui-popover-foreground);
|
|
4062
|
+
border: 1px solid var(--authui-border);
|
|
4063
|
+
border-radius: var(--authui-radius-md);
|
|
4064
|
+
box-shadow: var(--authui-shadow-lg);
|
|
4065
|
+
padding: 4px;
|
|
4066
|
+
z-index: var(--authui-z);
|
|
4067
|
+
display: flex;
|
|
4068
|
+
flex-direction: column;
|
|
4069
|
+
gap: 2px;
|
|
4070
|
+
}
|
|
4071
|
+
.menu-header {
|
|
4072
|
+
padding: 8px 10px 10px;
|
|
4073
|
+
display: flex;
|
|
4074
|
+
flex-direction: column;
|
|
4075
|
+
gap: 2px;
|
|
4076
|
+
border-bottom: 1px solid var(--authui-border);
|
|
4077
|
+
margin-bottom: 4px;
|
|
4078
|
+
}
|
|
4079
|
+
.menu-item {
|
|
4080
|
+
display: flex;
|
|
4081
|
+
align-items: center;
|
|
4082
|
+
gap: 8px;
|
|
4083
|
+
padding: 6px 10px;
|
|
4084
|
+
border-radius: var(--authui-radius-sm);
|
|
4085
|
+
border: 0;
|
|
4086
|
+
background: transparent;
|
|
4087
|
+
color: inherit;
|
|
4088
|
+
font: inherit;
|
|
4089
|
+
font-size: 14px;
|
|
4090
|
+
cursor: pointer;
|
|
4091
|
+
text-align: start;
|
|
4092
|
+
width: 100%;
|
|
4093
|
+
}
|
|
4094
|
+
.menu-item:hover,
|
|
4095
|
+
.menu-item:focus-visible {
|
|
4096
|
+
background: var(--authui-accent);
|
|
4097
|
+
outline: none;
|
|
4098
|
+
}
|
|
4099
|
+
.menu-item svg {
|
|
4100
|
+
width: 16px;
|
|
4101
|
+
height: 16px;
|
|
4102
|
+
color: var(--authui-muted-foreground);
|
|
4103
|
+
}
|
|
4104
|
+
.avatar {
|
|
4105
|
+
width: 32px;
|
|
4106
|
+
height: 32px;
|
|
4107
|
+
font-size: 13px;
|
|
4108
|
+
}
|
|
4109
|
+
`
|
|
4110
|
+
];
|
|
4111
|
+
q([
|
|
4112
|
+
g({ type: String })
|
|
4113
|
+
], I.prototype, "src", 2);
|
|
4114
|
+
q([
|
|
4115
|
+
d()
|
|
4116
|
+
], I.prototype, "menuOpen", 2);
|
|
4117
|
+
I = q([
|
|
4118
|
+
S("authui-user-button")
|
|
4119
|
+
], I);
|
|
4120
|
+
export {
|
|
4121
|
+
rt as A,
|
|
4122
|
+
b as E,
|
|
4123
|
+
o as a,
|
|
4124
|
+
p as b,
|
|
4125
|
+
Ut as c,
|
|
4126
|
+
M as d,
|
|
4127
|
+
v as e,
|
|
4128
|
+
x as f,
|
|
4129
|
+
P as g,
|
|
4130
|
+
$ as h,
|
|
4131
|
+
Y as i,
|
|
4132
|
+
K as j,
|
|
4133
|
+
I as k,
|
|
4134
|
+
et as l,
|
|
4135
|
+
Z as m,
|
|
4136
|
+
R as o,
|
|
4137
|
+
E as p,
|
|
4138
|
+
_ as t
|
|
4139
|
+
};
|