paskia 0.8.0__py3-none-any.whl → 0.9.0__py3-none-any.whl

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.
Files changed (67) hide show
  1. paskia/_version.py +2 -2
  2. paskia/authsession.py +14 -27
  3. paskia/bootstrap.py +31 -103
  4. paskia/config.py +0 -1
  5. paskia/db/__init__.py +26 -51
  6. paskia/db/background.py +17 -37
  7. paskia/db/jsonl.py +168 -6
  8. paskia/db/migrations.py +34 -0
  9. paskia/db/operations.py +400 -723
  10. paskia/db/structs.py +214 -90
  11. paskia/fastapi/__main__.py +89 -189
  12. paskia/fastapi/admin.py +103 -162
  13. paskia/fastapi/api.py +49 -85
  14. paskia/fastapi/mainapp.py +30 -19
  15. paskia/fastapi/remote.py +16 -39
  16. paskia/fastapi/reset.py +27 -17
  17. paskia/fastapi/session.py +2 -2
  18. paskia/fastapi/user.py +21 -27
  19. paskia/fastapi/ws.py +27 -62
  20. paskia/fastapi/wschat.py +62 -0
  21. paskia/frontend-build/auth/admin/index.html +5 -5
  22. paskia/frontend-build/auth/assets/{AccessDenied-Bc249ASC.css → AccessDenied-DPkUS8LZ.css} +1 -1
  23. paskia/frontend-build/auth/assets/AccessDenied-Fmeb6EtF.js +8 -0
  24. paskia/frontend-build/auth/assets/{RestrictedAuth-DgdJyscT.css → RestrictedAuth-CvR33_Z0.css} +1 -1
  25. paskia/frontend-build/auth/assets/RestrictedAuth-DsJXicIw.js +1 -0
  26. paskia/frontend-build/auth/assets/{_plugin-vue_export-helper-rKFEraYH.js → _plugin-vue_export-helper-nhjnO_bd.js} +1 -1
  27. paskia/frontend-build/auth/assets/admin-CPE1pLMm.js +1 -0
  28. paskia/frontend-build/auth/assets/{admin-BeNu48FR.css → admin-DzzjSg72.css} +1 -1
  29. paskia/frontend-build/auth/assets/{auth-BKX7shEe.css → auth-C7k64Wad.css} +1 -1
  30. paskia/frontend-build/auth/assets/auth-YIZvPlW_.js +1 -0
  31. paskia/frontend-build/auth/assets/{forward-Dzg-aE1C.js → forward-DmqVHZ7e.js} +1 -1
  32. paskia/frontend-build/auth/assets/reset-Chtv69AT.css +1 -0
  33. paskia/frontend-build/auth/assets/reset-s20PATTN.js +1 -0
  34. paskia/frontend-build/auth/assets/{restricted-C0IQufuH.js → restricted-D3AJx3_6.js} +1 -1
  35. paskia/frontend-build/auth/index.html +5 -5
  36. paskia/frontend-build/auth/restricted/index.html +4 -4
  37. paskia/frontend-build/int/forward/index.html +4 -4
  38. paskia/frontend-build/int/reset/index.html +3 -3
  39. paskia/globals.py +2 -2
  40. paskia/migrate/__init__.py +62 -55
  41. paskia/migrate/sql.py +72 -22
  42. paskia/remoteauth.py +1 -2
  43. paskia/sansio.py +6 -12
  44. {paskia-0.8.0.dist-info → paskia-0.9.0.dist-info}/METADATA +3 -2
  45. paskia-0.9.0.dist-info/RECORD +57 -0
  46. paskia/frontend-build/auth/assets/AccessDenied-aTdCvz9k.js +0 -8
  47. paskia/frontend-build/auth/assets/RestrictedAuth-BLMK7-nL.js +0 -1
  48. paskia/frontend-build/auth/assets/admin-tVs8oyLv.js +0 -1
  49. paskia/frontend-build/auth/assets/auth-Dk3q4pNS.js +0 -1
  50. paskia/frontend-build/auth/assets/reset-BWF4cWKR.css +0 -1
  51. paskia/frontend-build/auth/assets/reset-C_Td1_jn.js +0 -1
  52. paskia/util/frontend.py +0 -75
  53. paskia/util/hostutil.py +0 -76
  54. paskia/util/htmlutil.py +0 -47
  55. paskia/util/passphrase.py +0 -20
  56. paskia/util/permutil.py +0 -43
  57. paskia/util/pow.py +0 -45
  58. paskia/util/querysafe.py +0 -11
  59. paskia/util/sessionutil.py +0 -38
  60. paskia/util/startupbox.py +0 -75
  61. paskia/util/timeutil.py +0 -47
  62. paskia/util/useragent.py +0 -10
  63. paskia/util/userinfo.py +0 -145
  64. paskia/util/wordlist.py +0 -54
  65. paskia-0.8.0.dist-info/RECORD +0 -68
  66. {paskia-0.8.0.dist-info → paskia-0.9.0.dist-info}/WHEEL +0 -0
  67. {paskia-0.8.0.dist-info → paskia-0.9.0.dist-info}/entry_points.txt +0 -0
paskia/fastapi/ws.py CHANGED
@@ -1,40 +1,21 @@
1
- from uuid import UUID
2
-
3
1
  from fastapi import FastAPI, WebSocket
4
2
 
5
3
  from paskia import db
6
- from paskia.authsession import expires, get_reset, get_session
4
+ from paskia.authsession import expires, get_reset
7
5
  from paskia.fastapi import authz, remote
8
6
  from paskia.fastapi.session import AUTH_COOKIE, infodict
7
+ from paskia.fastapi.wschat import authenticate_chat, register_chat
9
8
  from paskia.fastapi.wsutil import validate_origin, websocket_error_handler
10
9
  from paskia.globals import passkey
11
10
  from paskia.util import hostutil, passphrase
12
11
 
13
12
  # Create a FastAPI subapp for WebSocket endpoints
14
- app = FastAPI()
13
+ app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)
15
14
 
16
15
  # Mount the remote auth WebSocket endpoints
17
16
  app.mount("/remote-auth", remote.app)
18
17
 
19
18
 
20
- async def register_chat(
21
- ws: WebSocket,
22
- user_uuid: UUID,
23
- user_name: str,
24
- origin: str,
25
- credential_ids: list[bytes] | None = None,
26
- ):
27
- """Generate registration options and send them to the client."""
28
- options, challenge = passkey.instance.reg_generate_options(
29
- user_id=user_uuid,
30
- user_name=user_name,
31
- credential_ids=credential_ids,
32
- )
33
- await ws.send_json({"optionsJSON": options})
34
- response = await ws.receive_json()
35
- return passkey.instance.reg_verify(response, challenge, user_uuid, origin=origin)
36
-
37
-
38
19
  @app.websocket("/register")
39
20
  @websocket_error_handler
40
21
  async def websocket_register_add(
@@ -56,25 +37,25 @@ async def websocket_register_add(
56
37
  raise ValueError(
57
38
  f"The reset link for {passkey.instance.rp_name} is invalid or has expired"
58
39
  )
59
- s = await get_reset(reset)
60
- user_uuid = s.user_uuid
40
+ s = get_reset(reset)
41
+ user_uuid = s.user
61
42
  else:
62
43
  # Require recent authentication for adding a new passkey
63
44
  ctx = await authz.verify(auth, perm=[], host=host, max_age="5m")
64
- user_uuid = ctx.session.user_uuid
45
+ user_uuid = ctx.session.user
65
46
  s = ctx.session
66
47
 
67
48
  # Get user information and determine effective user_name for this registration
68
- user = db.get_user_by_uuid(user_uuid)
49
+ user = db.data().users.get(user_uuid)
69
50
  user_name = user.display_name
70
51
  if name is not None:
71
52
  stripped = name.strip()
72
53
  if stripped:
73
54
  user_name = stripped
74
- challenge_ids = db.get_credentials_by_user_uuid(user_uuid)
55
+ credential_ids = db.get_user_credential_ids(user_uuid) or None
75
56
 
76
57
  # WebAuthn registration
77
- credential = await register_chat(ws, user_uuid, user_name, origin, challenge_ids)
58
+ credential = await register_chat(ws, user_uuid, user_name, origin, credential_ids)
78
59
 
79
60
  # Create a new session and store everything in database
80
61
  metadata = infodict(ws, "authenticated")
@@ -84,16 +65,16 @@ async def websocket_register_add(
84
65
  reset_key=(s.key if reset is not None else None),
85
66
  display_name=user_name,
86
67
  host=host,
87
- ip=metadata.get("ip"),
88
- user_agent=metadata.get("user_agent"),
68
+ ip=metadata["ip"],
69
+ user_agent=metadata["user_agent"],
89
70
  )
90
71
  auth = token
91
72
 
92
73
  assert isinstance(auth, str) and len(auth) == 16
93
74
  await ws.send_json(
94
75
  {
95
- "user_uuid": str(user.uuid),
96
- "credential_uuid": str(credential.uuid),
76
+ "user": str(user.uuid),
77
+ "credential": str(credential.uuid),
97
78
  "session_token": auth,
98
79
  "message": "New credential added successfully",
99
80
  }
@@ -110,36 +91,19 @@ async def websocket_authenticate(ws: WebSocket, auth=AUTH_COOKIE):
110
91
  session_user_uuid = None
111
92
  credential_ids = None
112
93
  if auth:
113
- try:
114
- session = await get_session(auth, host=host)
115
- session_user_uuid = session.user_uuid
116
- credential_ids = db.get_credentials_by_user_uuid(session_user_uuid)
117
- except ValueError:
118
- pass # Invalid/expired session - allow normal authentication
119
-
120
- options, challenge = passkey.instance.auth_generate_options(
121
- credential_ids=credential_ids
122
- )
123
- await ws.send_json({"optionsJSON": options})
124
- # Wait for the client to use his authenticator to authenticate
125
- credential = passkey.instance.auth_parse(await ws.receive_json())
126
- # Fetch from the database by credential ID
127
- try:
128
- stored_cred = db.get_credential_by_id(credential.raw_id)
129
- except ValueError:
130
- raise ValueError(
131
- f"This passkey is no longer registered with {passkey.instance.rp_name}"
132
- )
94
+ ctx = db.get_session_context(auth, host)
95
+ if ctx:
96
+ session_user_uuid = ctx.user.uuid
97
+ credential_ids = db.get_user_credential_ids(session_user_uuid) or None
98
+
99
+ cred, new_sign_count = await authenticate_chat(ws, origin, credential_ids)
133
100
 
134
101
  # If reauth mode, verify the credential belongs to the session's user
135
- if session_user_uuid and stored_cred.user_uuid != session_user_uuid:
102
+ if session_user_uuid and cred.user != session_user_uuid:
136
103
  raise ValueError("This passkey belongs to a different account")
137
104
 
138
- # Verify the credential matches the stored data
139
- passkey.instance.auth_verify(credential, challenge, stored_cred, origin)
140
-
141
105
  # Create session and update user/credential in a single transaction
142
- assert stored_cred.uuid is not None
106
+ assert cred.uuid is not None
143
107
  metadata = infodict(ws, "auth")
144
108
  normalized_host = hostutil.normalize_host(host)
145
109
  if not normalized_host:
@@ -150,17 +114,18 @@ async def websocket_authenticate(ws: WebSocket, auth=AUTH_COOKIE):
150
114
  raise ValueError(f"Host must be the same as or a subdomain of {rp_id}")
151
115
 
152
116
  token = db.login(
153
- user_uuid=stored_cred.user_uuid,
154
- credential=stored_cred,
117
+ user_uuid=cred.user,
118
+ credential_uuid=cred.uuid,
119
+ sign_count=new_sign_count,
155
120
  host=normalized_host,
156
- ip=metadata.get("ip") or "",
157
- user_agent=metadata.get("user_agent") or "",
121
+ ip=metadata["ip"],
122
+ user_agent=metadata["user_agent"],
158
123
  expiry=expires(),
159
124
  )
160
125
 
161
126
  await ws.send_json(
162
127
  {
163
- "user_uuid": str(stored_cred.user_uuid),
128
+ "user": str(cred.user),
164
129
  "session_token": token,
165
130
  }
166
131
  )
@@ -0,0 +1,62 @@
1
+ """
2
+ WebSocket chat functions for WebAuthn registration and authentication flows.
3
+ """
4
+
5
+ from uuid import UUID
6
+
7
+ from fastapi import WebSocket
8
+
9
+ from paskia import db
10
+ from paskia.db import Credential
11
+ from paskia.globals import passkey
12
+
13
+
14
+ async def register_chat(
15
+ ws: WebSocket,
16
+ user_uuid: UUID,
17
+ user_name: str,
18
+ origin: str,
19
+ credential_ids: list[bytes] | None = None,
20
+ ):
21
+ """Run WebAuthn registration flow and return the verified credential."""
22
+ options, challenge = passkey.instance.reg_generate_options(
23
+ user_id=user_uuid,
24
+ user_name=user_name,
25
+ credential_ids=credential_ids,
26
+ )
27
+ await ws.send_json({"optionsJSON": options})
28
+ response = await ws.receive_json()
29
+ return passkey.instance.reg_verify(response, challenge, user_uuid, origin=origin)
30
+
31
+
32
+ async def authenticate_chat(
33
+ ws: WebSocket,
34
+ origin: str,
35
+ credential_ids: list[bytes] | None = None,
36
+ ) -> tuple[Credential, int]:
37
+ """Run WebAuthn authentication flow and return the credential and new sign count.
38
+
39
+ Returns:
40
+ tuple of (credential, new_sign_count) where new_sign_count comes from WebAuthn verification
41
+ """
42
+ options, challenge = passkey.instance.auth_generate_options(
43
+ credential_ids=credential_ids
44
+ )
45
+ await ws.send_json({"optionsJSON": options})
46
+ authcred = passkey.instance.auth_parse(await ws.receive_json())
47
+
48
+ cred = next(
49
+ (
50
+ c
51
+ for c in db.data().credentials.values()
52
+ if c.credential_id == authcred.raw_id
53
+ ),
54
+ None,
55
+ )
56
+ if not cred:
57
+ raise ValueError(
58
+ f"This passkey is no longer registered with {passkey.instance.rp_name}"
59
+ )
60
+
61
+ verification = passkey.instance.auth_verify(authcred, challenge, cred, origin)
62
+ return cred, verification.new_sign_count
@@ -4,13 +4,13 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Admin</title>
7
- <script type="module" crossorigin src="/auth/assets/admin-tVs8oyLv.js"></script>
8
- <link rel="modulepreload" crossorigin href="/auth/assets/_plugin-vue_export-helper-rKFEraYH.js">
7
+ <script type="module" crossorigin src="/auth/assets/admin-CPE1pLMm.js"></script>
8
+ <link rel="modulepreload" crossorigin href="/auth/assets/_plugin-vue_export-helper-nhjnO_bd.js">
9
9
  <link rel="modulepreload" crossorigin href="/auth/assets/helpers-DzjFIx78.js">
10
- <link rel="modulepreload" crossorigin href="/auth/assets/AccessDenied-aTdCvz9k.js">
10
+ <link rel="modulepreload" crossorigin href="/auth/assets/AccessDenied-Fmeb6EtF.js">
11
11
  <link rel="stylesheet" crossorigin href="/auth/assets/_plugin-vue_export-helper-BTzJAQlS.css">
12
- <link rel="stylesheet" crossorigin href="/auth/assets/AccessDenied-Bc249ASC.css">
13
- <link rel="stylesheet" crossorigin href="/auth/assets/admin-BeNu48FR.css">
12
+ <link rel="stylesheet" crossorigin href="/auth/assets/AccessDenied-DPkUS8LZ.css">
13
+ <link rel="stylesheet" crossorigin href="/auth/assets/admin-DzzjSg72.css">
14
14
  </head>
15
15
  <body>
16
16
  <div id="admin-app"></div>
@@ -1 +1 @@
1
- .breadcrumbs[data-v-6344dbb8]{margin:.25rem 0 .5rem;line-height:1.2;color:var(--color-text-muted)}.breadcrumbs ol[data-v-6344dbb8]{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem}.breadcrumbs li[data-v-6344dbb8]{display:inline-flex;align-items:center;gap:.25rem;font-size:.9rem}.breadcrumbs a[data-v-6344dbb8]{text-decoration:none;color:var(--color-link);padding:0 .25rem;border-radius:4px;transition:color .2s ease,background .2s ease}.breadcrumbs .sep[data-v-6344dbb8]{color:var(--color-text-muted);margin:0}.btn-card-delete{display:none}.credential-item:focus .btn-card-delete{display:block}.user-info.has-extra[data-v-ce373d6c]{grid-template-columns:auto 1fr 2fr;grid-template-areas:"heading heading extra" "org org extra" "label1 value1 extra" "label2 value2 extra" "label3 value3 extra"}.user-info[data-v-ce373d6c]:not(.has-extra){grid-template-columns:auto 1fr;grid-template-areas:"heading heading" "org org" "label1 value1" "label2 value2" "label3 value3"}@media(max-width:720px){.user-info.has-extra[data-v-ce373d6c]{grid-template-columns:auto 1fr;grid-template-areas:"heading heading" "org org" "label1 value1" "label2 value2" "label3 value3" "extra extra"}}.user-name-heading[data-v-ce373d6c]{grid-area:heading;display:flex;align-items:center;flex-wrap:wrap;margin:0 0 .25rem}.org-role-sub[data-v-ce373d6c]{grid-area:org;display:flex;flex-direction:column;margin:-.15rem 0 .25rem}.org-line[data-v-ce373d6c]{font-size:.7rem;font-weight:600;line-height:1.1;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em}.role-line[data-v-ce373d6c]{font-size:.65rem;color:var(--color-text-muted);line-height:1.1}.info-label[data-v-ce373d6c]:nth-of-type(1){grid-area:label1}.info-value[data-v-ce373d6c]:nth-of-type(2){grid-area:value1}.info-label[data-v-ce373d6c]:nth-of-type(3){grid-area:label2}.info-value[data-v-ce373d6c]:nth-of-type(4){grid-area:value2}.info-label[data-v-ce373d6c]:nth-of-type(5){grid-area:label3}.info-value[data-v-ce373d6c]:nth-of-type(6){grid-area:value3}.user-info-extra[data-v-ce373d6c]{grid-area:extra;padding-left:2rem;border-left:1px solid var(--color-border)}.user-name-row[data-v-ce373d6c]{display:inline-flex;align-items:center;gap:.35rem;max-width:100%}.user-name-row.editing[data-v-ce373d6c]{flex:1 1 auto}.display-name[data-v-ce373d6c]{font-weight:600;font-size:1.05em;line-height:1.2;max-width:14ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.name-input[data-v-ce373d6c]{width:auto;flex:1 1 140px;min-width:120px;padding:6px 8px;font-size:.9em;border:1px solid var(--color-border-strong);border-radius:6px;background:var(--color-surface);color:var(--color-text)}.user-name-heading .name-input[data-v-ce373d6c]{width:auto}.name-input[data-v-ce373d6c]:focus{outline:none;border-color:var(--color-accent);box-shadow:var(--focus-ring)}.mini-btn[data-v-ce373d6c]{width:auto;padding:4px 6px;margin:0;font-size:.75em;line-height:1;cursor:pointer}.mini-btn[data-v-ce373d6c]:hover:not(:disabled){background:var(--color-accent-soft);color:var(--color-accent)}.mini-btn[data-v-ce373d6c]:active:not(:disabled){transform:translateY(1px)}.mini-btn[data-v-ce373d6c]:disabled{opacity:.5;cursor:not-allowed}@media(max-width:720px){.user-info-extra[data-v-ce373d6c]{padding-left:0;padding-top:1rem;margin-top:1rem;border-left:none;border-top:1px solid var(--color-border)}}dialog[data-v-2ebcbb0a]{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-xl);padding:calc(var(--space-lg) - var(--space-xs));max-width:500px;width:min(500px,90vw);max-height:90vh;overflow-y:auto;position:fixed;inset:0;margin:auto;height:fit-content}dialog[data-v-2ebcbb0a]::backdrop{background:transparent;backdrop-filter:blur(.1rem) brightness(.7);-webkit-backdrop-filter:blur(.1rem) brightness(.7)}dialog[data-v-2ebcbb0a] .modal-title,dialog[data-v-2ebcbb0a] h3{margin:0 0 var(--space-md);font-size:1.25rem;font-weight:600;color:var(--color-heading)}dialog[data-v-2ebcbb0a] form{display:flex;flex-direction:column;gap:var(--space-md)}dialog[data-v-2ebcbb0a] .modal-form{display:flex;flex-direction:column;gap:var(--space-md)}dialog[data-v-2ebcbb0a] .modal-form label{display:flex;flex-direction:column;gap:var(--space-xs);font-weight:500}dialog[data-v-2ebcbb0a] .modal-form input,dialog[data-v-2ebcbb0a] .modal-form textarea{padding:var(--space-md);border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-bg);color:var(--color-text);font-size:1rem;line-height:1.4;min-height:2.5rem}dialog[data-v-2ebcbb0a] .modal-form input:focus,dialog[data-v-2ebcbb0a] .modal-form textarea:focus{outline:none;border-color:var(--color-accent);box-shadow:0 0 0 2px #c7d2fe}dialog[data-v-2ebcbb0a] .modal-actions{display:flex;justify-content:flex-end;gap:var(--space-sm);margin-top:var(--space-md);margin-bottom:var(--space-xs)}.name-edit-form[data-v-b73321cf]{display:flex;flex-direction:column;gap:var(--space-md)}.error[data-v-b73321cf]{color:var(--color-danger-text)}.small[data-v-b73321cf]{font-size:.9rem}.qr-display[data-v-727427c4]{display:flex;flex-direction:column;align-items:center;gap:.75rem}.qr-section[data-v-727427c4]{display:flex;flex-direction:column;align-items:center;gap:.5rem}.qr-link[data-v-727427c4]{display:flex;flex-direction:column;align-items:center;text-decoration:none;color:inherit;border-radius:var(--radius-sm, 6px);overflow:hidden}.qr-code[data-v-727427c4]{display:block;width:200px;height:200px;max-width:100%;object-fit:contain;border-radius:var(--radius-sm, 6px);background:#fff;cursor:pointer}.link-text[data-v-727427c4]{padding:.5rem;font-size:.75rem;color:var(--color-text-muted);font-family:monospace;word-break:break-all;line-height:1.2;transition:color .2s ease}.qr-link:hover .link-text[data-v-727427c4]{color:var(--color-text)}dialog[data-v-e04dd463]{border:none;background:transparent;padding:0;max-width:none;width:fit-content;height:fit-content;position:fixed;inset:0;margin:auto}dialog[data-v-e04dd463]::backdrop{-webkit-backdrop-filter:blur(.2rem) brightness(.5);backdrop-filter:blur(.2rem) brightness(.5)}.icon-btn[data-v-e04dd463]{background:none;border:none;cursor:pointer;font-size:1rem;opacity:.6}.icon-btn[data-v-e04dd463]:hover{opacity:1}.reg-header-row[data-v-e04dd463]{display:flex;justify-content:space-between;align-items:center;gap:.75rem;margin-bottom:.75rem}.reg-title[data-v-e04dd463]{margin:0;font-size:1.25rem;font-weight:600}.device-dialog[data-v-e04dd463]{background:var(--color-surface);padding:1.25rem 1.25rem 1rem;border-radius:var(--radius-md);max-width:480px;width:100%;box-shadow:0 6px 28px #00000040}.reg-help[data-v-e04dd463]{margin:.5rem 0 .75rem;font-size:.85rem;line-height:1.4;text-align:center;color:var(--color-text-muted)}.reg-actions[data-v-e04dd463]{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}.expiry-note[data-v-e04dd463]{font-size:.75rem;color:var(--color-text-muted);text-align:center;margin-top:.75rem}.loading-container[data-v-130f5abf]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;gap:1rem}.loading-spinner[data-v-130f5abf]{width:40px;height:40px;border:4px solid var(--color-border);border-top:4px solid var(--color-primary);border-radius:50%;animation:spin-130f5abf 1s linear infinite}@keyframes spin-130f5abf{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-container p[data-v-130f5abf]{color:var(--color-text-muted);margin:0}.message-container[data-v-744305d5]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;padding:2rem}.message-content[data-v-744305d5]{text-align:center;max-width:480px}.message-content h2[data-v-744305d5]{margin:0 0 1.5rem;color:var(--color-heading)}.message-content .button-row[data-v-744305d5]{display:flex;gap:.75rem;justify-content:center}
1
+ .breadcrumbs[data-v-6344dbb8]{margin:.25rem 0 .5rem;line-height:1.2;color:var(--color-text-muted)}.breadcrumbs ol[data-v-6344dbb8]{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem}.breadcrumbs li[data-v-6344dbb8]{display:inline-flex;align-items:center;gap:.25rem;font-size:.9rem}.breadcrumbs a[data-v-6344dbb8]{text-decoration:none;color:var(--color-link);padding:0 .25rem;border-radius:4px;transition:color .2s ease,background .2s ease}.breadcrumbs .sep[data-v-6344dbb8]{color:var(--color-text-muted);margin:0}.btn-card-delete{display:none}.credential-item:focus .btn-card-delete{display:block}.user-info.has-extra[data-v-ce373d6c]{grid-template-columns:auto 1fr 2fr;grid-template-areas:"heading heading extra" "org org extra" "label1 value1 extra" "label2 value2 extra" "label3 value3 extra"}.user-info[data-v-ce373d6c]:not(.has-extra){grid-template-columns:auto 1fr;grid-template-areas:"heading heading" "org org" "label1 value1" "label2 value2" "label3 value3"}@media(max-width:720px){.user-info.has-extra[data-v-ce373d6c]{grid-template-columns:auto 1fr;grid-template-areas:"heading heading" "org org" "label1 value1" "label2 value2" "label3 value3" "extra extra"}}.user-name-heading[data-v-ce373d6c]{grid-area:heading;display:flex;align-items:center;flex-wrap:wrap;margin:0 0 .25rem}.org-role-sub[data-v-ce373d6c]{grid-area:org;display:flex;flex-direction:column;margin:-.15rem 0 .25rem}.org-line[data-v-ce373d6c]{font-size:.7rem;font-weight:600;line-height:1.1;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em}.role-line[data-v-ce373d6c]{font-size:.65rem;color:var(--color-text-muted);line-height:1.1}.info-label[data-v-ce373d6c]:nth-of-type(1){grid-area:label1}.info-value[data-v-ce373d6c]:nth-of-type(2){grid-area:value1}.info-label[data-v-ce373d6c]:nth-of-type(3){grid-area:label2}.info-value[data-v-ce373d6c]:nth-of-type(4){grid-area:value2}.info-label[data-v-ce373d6c]:nth-of-type(5){grid-area:label3}.info-value[data-v-ce373d6c]:nth-of-type(6){grid-area:value3}.user-info-extra[data-v-ce373d6c]{grid-area:extra;padding-left:2rem;border-left:1px solid var(--color-border)}.user-name-row[data-v-ce373d6c]{display:inline-flex;align-items:center;gap:.35rem;max-width:100%}.user-name-row.editing[data-v-ce373d6c]{flex:1 1 auto}.display-name[data-v-ce373d6c]{font-weight:600;font-size:1.05em;line-height:1.2;max-width:14ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.name-input[data-v-ce373d6c]{width:auto;flex:1 1 140px;min-width:120px;padding:6px 8px;font-size:.9em;border:1px solid var(--color-border-strong);border-radius:6px;background:var(--color-surface);color:var(--color-text)}.user-name-heading .name-input[data-v-ce373d6c]{width:auto}.name-input[data-v-ce373d6c]:focus{outline:none;border-color:var(--color-accent);box-shadow:var(--focus-ring)}.mini-btn[data-v-ce373d6c]{width:auto;padding:4px 6px;margin:0;font-size:.75em;line-height:1;cursor:pointer}.mini-btn[data-v-ce373d6c]:hover:not(:disabled){background:var(--color-accent-soft);color:var(--color-accent)}.mini-btn[data-v-ce373d6c]:active:not(:disabled){transform:translateY(1px)}.mini-btn[data-v-ce373d6c]:disabled{opacity:.5;cursor:not-allowed}@media(max-width:720px){.user-info-extra[data-v-ce373d6c]{padding-left:0;padding-top:1rem;margin-top:1rem;border-left:none;border-top:1px solid var(--color-border)}}dialog[data-v-2ebcbb0a]{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-xl);padding:calc(var(--space-lg) - var(--space-xs));max-width:500px;width:min(500px,90vw);max-height:90vh;overflow-y:auto;position:fixed;inset:0;margin:auto;height:fit-content}dialog[data-v-2ebcbb0a]::backdrop{background:transparent;backdrop-filter:blur(.1rem) brightness(.7);-webkit-backdrop-filter:blur(.1rem) brightness(.7)}dialog[data-v-2ebcbb0a] .modal-title,dialog[data-v-2ebcbb0a] h3{margin:0 0 var(--space-md);font-size:1.25rem;font-weight:600;color:var(--color-heading)}dialog[data-v-2ebcbb0a] form{display:flex;flex-direction:column;gap:var(--space-md)}dialog[data-v-2ebcbb0a] .modal-form{display:flex;flex-direction:column;gap:var(--space-md)}dialog[data-v-2ebcbb0a] .modal-form label{display:flex;flex-direction:column;gap:var(--space-xs);font-weight:500}dialog[data-v-2ebcbb0a] .modal-form input,dialog[data-v-2ebcbb0a] .modal-form textarea{padding:var(--space-md);border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-bg);color:var(--color-text);font-size:1rem;line-height:1.4;min-height:2.5rem}dialog[data-v-2ebcbb0a] .modal-form input:focus,dialog[data-v-2ebcbb0a] .modal-form textarea:focus{outline:none;border-color:var(--color-accent);box-shadow:0 0 0 2px #c7d2fe}dialog[data-v-2ebcbb0a] .modal-actions{display:flex;justify-content:flex-end;gap:var(--space-sm);margin-top:var(--space-md);margin-bottom:var(--space-xs)}.name-edit-form[data-v-b73321cf]{display:flex;flex-direction:column;gap:var(--space-md)}.error[data-v-b73321cf]{color:var(--color-danger-text)}.small[data-v-b73321cf]{font-size:.9rem}.qr-display[data-v-727427c4]{display:flex;flex-direction:column;align-items:center;gap:.75rem}.qr-section[data-v-727427c4]{display:flex;flex-direction:column;align-items:center;gap:.5rem}.qr-link[data-v-727427c4]{display:flex;flex-direction:column;align-items:center;text-decoration:none;color:inherit;border-radius:var(--radius-sm, 6px);overflow:hidden}.qr-code[data-v-727427c4]{display:block;width:200px;height:200px;max-width:100%;object-fit:contain;border-radius:var(--radius-sm, 6px);background:#fff;cursor:pointer}.link-text[data-v-727427c4]{padding:.5rem;font-size:.75rem;color:var(--color-text-muted);font-family:monospace;word-break:break-all;line-height:1.2;transition:color .2s ease}.qr-link:hover .link-text[data-v-727427c4]{color:var(--color-text)}dialog[data-v-e04dd463]{border:none;background:transparent;padding:0;max-width:none;width:fit-content;height:fit-content;position:fixed;inset:0;margin:auto}dialog[data-v-e04dd463]::backdrop{-webkit-backdrop-filter:blur(.2rem) brightness(.5);backdrop-filter:blur(.2rem) brightness(.5)}.icon-btn[data-v-e04dd463]{background:none;border:none;cursor:pointer;font-size:1rem;opacity:.6}.icon-btn[data-v-e04dd463]:hover{opacity:1}.reg-header-row[data-v-e04dd463]{display:flex;justify-content:space-between;align-items:center;gap:.75rem;margin-bottom:.75rem}.reg-title[data-v-e04dd463]{margin:0;font-size:1.25rem;font-weight:600}.device-dialog[data-v-e04dd463]{background:var(--color-surface);padding:1.25rem 1.25rem 1rem;border-radius:var(--radius-md);max-width:480px;width:100%;box-shadow:0 6px 28px #00000040}.reg-help[data-v-e04dd463]{margin:.5rem 0 .75rem;font-size:.85rem;line-height:1.4;text-align:center;color:var(--color-text-muted)}.reg-actions[data-v-e04dd463]{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}.expiry-note[data-v-e04dd463]{font-size:.75rem;color:var(--color-text-muted);text-align:center;margin-top:.75rem}.loading-container[data-v-130f5abf]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;gap:1rem}.loading-spinner[data-v-130f5abf]{width:40px;height:40px;border:4px solid var(--color-border);border-top:4px solid var(--color-primary);border-radius:50%;animation:spin-130f5abf 1s linear infinite}@keyframes spin-130f5abf{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.loading-container p[data-v-130f5abf]{color:var(--color-text-muted);margin:0}.message-container[data-v-a7b258e7]{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;padding:2rem}.message-content[data-v-a7b258e7]{text-align:center;max-width:480px}.message-content h2[data-v-a7b258e7]{margin:0 0 1rem;color:var(--color-heading)}.message-content .error-detail[data-v-a7b258e7]{margin:0 0 1.5rem;color:var(--color-text-muted)}.message-content .button-row[data-v-a7b258e7]{display:flex;gap:.75rem;justify-content:center}
@@ -0,0 +1,8 @@
1
+ import{M as At,r as F,N as Rt,O as Yt,P as ue,Q as Tt,R as Qt,S as Gt,T as Wt,n as ze,U as Zt,c as x,w as He,V as Xt,W as en,H as Q,m as tn,X as nn,Y as on,b as R,f as L,z as U,d as T,e as v,t as D,g as se,_ as Y,F as oe,i as ce,B as z,D as Mt,l as de,Z as Nt,$ as Pt,a0 as Dt,a1 as Lt,o as qt,a2 as rn,a as Ft,C as sn,k as xe,h as an,a3 as ln,L as un,x as cn}from"./_plugin-vue_export-helper-nhjnO_bd.js";import{f as G,h as ae,g as We}from"./helpers-DzjFIx78.js";let Ut;const fe=e=>Ut=e,Kt=Symbol();function Oe(e){return e&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"&&typeof e.toJSON!="function"}var re;(function(e){e.direct="direct",e.patchObject="patch object",e.patchFunction="patch function"})(re||(re={}));function vr(){const e=At(!0),s=e.run(()=>F({}));let r=[],t=[];const n=Rt({install(o){fe(n),n._a=o,o.provide(Kt,n),o.config.globalProperties.$pinia=n,t.forEach(i=>r.push(i)),t=[]},use(o){return this._a?r.push(o):t.push(o),this},_p:r,_a:null,_e:e,_s:new Map,state:s});return n}const Vt=()=>{};function Ze(e,s,r,t=Vt){e.add(s);const n=()=>{e.delete(s)&&t()};return!r&&Gt()&&Wt(n),n}function ee(e,...s){e.forEach(r=>{r(...s)})}const dn=e=>e(),Xe=Symbol(),pe=Symbol();function je(e,s){e instanceof Map&&s instanceof Map?s.forEach((r,t)=>e.set(t,r)):e instanceof Set&&s instanceof Set&&s.forEach(e.add,e);for(const r in s){if(!s.hasOwnProperty(r))continue;const t=s[r],n=e[r];Oe(n)&&Oe(t)&&e.hasOwnProperty(r)&&!ue(t)&&!Tt(t)?e[r]=je(n,t):e[r]=t}return e}const fn=Symbol();function hn(e){return!Oe(e)||!Object.prototype.hasOwnProperty.call(e,fn)}const{assign:J}=Object;function gn(e){return!!(ue(e)&&e.effect)}function mn(e,s,r,t){const{state:n,actions:o,getters:i}=s,a=r.state.value[e];let l;function u(){a||(r.state.value[e]=n?n():{});const f=Zt(r.state.value[e]);return J(f,o,Object.keys(i||{}).reduce((w,b)=>(w[b]=Rt(x(()=>{fe(r);const h=r._s.get(e);return i[b].call(h,h)})),w),{}))}return l=Ht(e,u,s,r,t,!0),l}function Ht(e,s,r={},t,n,o){let i;const a=J({actions:{}},r),l={deep:!0};let u,f,w=new Set,b=new Set,h;const d=t.state.value[e];!o&&!d&&(t.state.value[e]={}),F({});let g;function N(y){let m;u=f=!1,typeof y=="function"?(y(t.state.value[e]),m={type:re.patchFunction,storeId:e,events:h}):(je(t.state.value[e],y),m={type:re.patchObject,payload:y,storeId:e,events:h});const E=g=Symbol();ze().then(()=>{g===E&&(u=!0)}),f=!0,ee(w,m,t.state.value[e])}const A=o?function(){const{state:m}=r,E=m?m():{};this.$patch(_=>{J(_,E)})}:Vt;function P(){i.stop(),w.clear(),b.clear(),t._s.delete(e)}const c=(y,m="")=>{if(Xe in y)return y[pe]=m,y;const E=function(){fe(t);const _=Array.from(arguments),k=new Set,B=new Set;function M(q){k.add(q)}function V(q){B.add(q)}ee(b,{args:_,name:E[pe],store:I,after:M,onError:V});let K;try{K=y.apply(this&&this.$id===e?this:I,_)}catch(q){throw ee(B,q),q}return K instanceof Promise?K.then(q=>(ee(k,q),q)).catch(q=>(ee(B,q),Promise.reject(q))):(ee(k,K),K)};return E[Xe]=!0,E[pe]=m,E},S={_p:t,$id:e,$onAction:Ze.bind(null,b),$patch:N,$reset:A,$subscribe(y,m={}){const E=Ze(w,y,m.detached,()=>_()),_=i.run(()=>He(()=>t.state.value[e],k=>{(m.flush==="sync"?f:u)&&y({storeId:e,type:re.direct,events:h},k)},J({},l,m)));return E},$dispose:P},I=Yt(S);t._s.set(e,I);const p=(t._a&&t._a.runWithContext||dn)(()=>t._e.run(()=>(i=At()).run(()=>s({action:c}))));for(const y in p){const m=p[y];if(ue(m)&&!gn(m)||Tt(m))o||(d&&hn(m)&&(ue(m)?m.value=d[y]:je(m,d[y])),t.state.value[e][y]=m);else if(typeof m=="function"){const E=c(m,y);p[y]=E,a.actions[y]=m}}return J(I,p),J(Qt(I),p),Object.defineProperty(I,"$state",{get:()=>t.state.value[e],set:y=>{N(m=>{J(m,y)})}}),t._p.forEach(y=>{J(I,i.run(()=>y({store:I,app:t._a,pinia:t,options:a})))}),d&&o&&r.hydrate&&r.hydrate(I.$state,d),u=!0,f=!0,I}function yn(e,s,r){let t;const n=typeof s=="function";t=n?r:s;function o(i,a){const l=en();return i=i||(l?Xt(Kt,null):null),i&&fe(i),i=Ut,i._s.has(e)||(n?Ht(e,s,t,i):mn(e,t,i)),i._s.get(e)}return o.$id=e,o}const $e=yn("auth",{state:()=>({userInfo:null,isLoading:!1,settings:null,currentView:"login",status:{message:"",type:"info",show:!1}}),getters:{},actions:{setLoading(e){this.isLoading=!!e},showMessage(e,s="info",r=null){const t=r??(s==="error"?5e3:3e3);this.status={message:e,type:s,show:!0},t>0&&setTimeout(()=>{this.status.show=!1},t)},async setSessionCookie(e){if(!e?.session_token)throw console.error("setSessionCookie called with missing session_token:",e),new Error("Authentication response missing session_token");return await Q("/auth/api/set-session",{method:"POST",headers:{Authorization:`Bearer ${e.session_token}`}})},async register(){this.isLoading=!0;try{const e=await on();return await this.setSessionCookie(e),await this.loadUserInfo(),this.selectView(),e}finally{this.isLoading=!1}},async authenticate(){this.isLoading=!0;try{const e=await nn();return await this.setSessionCookie(e),await this.loadUserInfo(),this.selectView(),e}finally{this.isLoading=!1}},selectView(){this.userInfo?this.currentView="profile":this.currentView="login"},async loadSettings(){this.settings=await tn()},async loadUserInfo(){try{this.userInfo=await Q("/auth/api/user-info",{method:"POST"}),console.log("User info loaded:",this.userInfo)}catch(e){throw e.status===401||e.status===403?console.log("Authentication required:",e.message):this.showMessage(e.message||"Failed to load user info","error",5e3),e}},async deleteCredential(e){await Q(`/auth/api/user/credential/${e}`,{method:"DELETE"}),await this.loadUserInfo()},async terminateSession(e){try{if((await Q(`/auth/api/user/session/${e}`,{method:"DELETE"}))?.current_session_terminated){sessionStorage.clear(),location.reload();return}await this.loadUserInfo(),this.showMessage("Session terminated","success",2500)}catch(s){throw console.error("Terminate session error:",s),s}},async logout(){try{await Q("/auth/api/logout",{method:"POST"}),sessionStorage.clear(),location.reload()}catch(e){console.error("Logout error:",e),e.status!==401&&e.status!==403&&this.showMessage(e.message,"error")}},async logoutEverywhere(){try{await Q("/auth/api/user/logout-all",{method:"POST"}),sessionStorage.clear(),location.reload()}catch(e){console.error("Logout-all error:",e),e.status!==401&&e.status!==403&&this.showMessage(e.message,"error")}}}}),pn={key:0,class:"global-status",style:{display:"block"}},Cr={__name:"StatusMessage",setup(e){const s=$e();return(r,t)=>U(s).status.show?(T(),R("div",pn,[v("div",{class:se(["status",U(s).status.type])},D(U(s).status.message),3)])):L("",!0)}},wn=["href"],bn={key:0,class:"sep"},vn={__name:"Breadcrumbs",props:{entries:{type:Array,default:()=>[]},showHome:{type:Boolean,default:!0},homeHref:{type:String,default:"/"}},setup(e,{expose:s}){const r=e,t=F(null),n=x(()=>r.showHome&&r.entries.length>0&&r.entries[0].href===r.homeHref?[{label:"🏠 "+r.entries[0].label,href:r.homeHref},...r.entries.slice(1)]:[...r.showHome?[{label:"🏠",href:r.homeHref}]:[],...r.entries]),o=x(()=>{const u=window.location.hash||window.location.pathname;for(let f=n.value.length-1;f>=0;f--){const w=n.value[f].href;if(w===u||w&&u.startsWith(w))return f}return n.value.length-1});function i(u){if(u.target===t.value){const f=t.value.querySelectorAll("a"),w=Math.min(o.value,f.length-1);f[w]&&f[w].focus()}}function a(u){const f=z(u);f&&(f==="left"||f==="right")&&(u.preventDefault(),Mt(t.value,u.target,f,{itemSelector:"a"}))}function l(){const u=t.value?.querySelectorAll("a");if(u?.length){const f=Math.min(o.value,u.length-1);u[f]?.focus()}}return s({focusCurrent:l}),(u,f)=>n.value.length>1?(T(),R("nav",{key:0,ref_key:"navRef",ref:t,class:"breadcrumbs","aria-label":"Breadcrumb",tabindex:"0",onFocusin:i,onKeydown:a},[v("ol",null,[(T(!0),R(oe,null,ce(n.value,(w,b)=>(T(),R("li",{key:b},[v("a",{href:w.href,tabindex:"-1"},D(w.label),9,wn),b<n.value.length-1?(T(),R("span",bn," — ")):L("",!0)]))),128))])],544)):L("",!0)}},Sr=Y(vn,[["__scopeId","data-v-6344dbb8"]]),Cn={key:0},Sn={key:1},En=["onFocusin","onKeydown"],_n={class:"item-top"},kn={class:"item-icon"},Bn=["src","alt"],In={key:1,class:"auth-emoji"},An={class:"item-title"},Rn={class:"item-actions"},Tn={key:0,class:"badge badge-current"},Mn={key:1,class:"badge badge-current"},Nn={key:2,class:"badge badge-current"},Pn=["onClick","disabled","title"],Dn={class:"item-details"},Ln={class:"credential-dates"},qn={class:"date-value"},Fn={class:"date-value"},Un={class:"date-value"},Er={__name:"CredentialList",props:{credentials:{type:Array,default:()=>[]},aaguidInfo:{type:Object,default:()=>({})},loading:{type:Boolean,default:!1},allowDelete:{type:Boolean,default:!1},hoveredCredentialUuid:{type:String,default:null},hoveredSessionCredentialUuid:{type:String,default:null},navigationDisabled:{type:Boolean,default:!1}},emits:["delete","credentialHover","navigate-out"],setup(e,{emit:s}){const r=e,t=s,n=h=>{t("credentialHover",h)},o=h=>{h.currentTarget.contains(h.relatedTarget)||t("credentialHover",null)},i=h=>{h.currentTarget.matches(":focus")||(h.currentTarget.focus(),h.stopPropagation())},a=(h,d)=>{Pt(h,()=>{r.allowDelete&&!d.is_current_session&&t("delete",d)})},l=h=>{if(r.navigationDisabled)return;const d=h.currentTarget;if(h.target===d){const g=d.querySelector(".credential-item");g&&g.focus()}},u=h=>{r.navigationDisabled||Dt(h,d=>t("navigate-out",d))},f=(h,d)=>{if(a(h,d),h.defaultPrevented||r.navigationDisabled)return;const g=z(h);if(g){h.preventDefault();const N=h.currentTarget.closest(".credential-list");Nt(N,h.currentTarget,g,{itemSelector:".credential-item"})==="boundary"&&t("navigate-out",g)}},w=h=>{const d=r.aaguidInfo?.[h.aaguid];return d?d.name:"Unknown Authenticator"},b=h=>{const d=r.aaguidInfo?.[h.aaguid];if(!d)return null;const N=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"icon_dark":"icon_light";return d[N]||null};return(h,d)=>(T(),R("div",{class:"credential-list",tabindex:"0",onFocusin:l,onKeydown:u},[e.loading?(T(),R("div",Cn,[...d[2]||(d[2]=[v("p",null,"Loading credentials...",-1)])])):e.credentials?.length?(T(!0),R(oe,{key:2},ce(e.credentials,g=>(T(),R("div",{key:g.credential,class:se(["credential-item",{"current-session":g.is_current_session&&!e.hoveredCredentialUuid&&!e.hoveredSessionCredentialUuid,"is-hovered":e.hoveredCredentialUuid===g.credential,"is-linked-session":e.hoveredSessionCredentialUuid===g.credential}]),tabindex:"-1",onMousedown:d[0]||(d[0]=de(()=>{},["prevent"])),onClickCapture:i,onFocusin:N=>n(g.credential),onFocusout:d[1]||(d[1]=N=>o(N)),onKeydown:N=>f(N,g)},[v("div",_n,[v("div",kn,[b(g)?(T(),R("img",{key:0,src:b(g),alt:w(g),class:"auth-icon",width:"32",height:"32"},null,8,Bn)):(T(),R("span",In,"🔑"))]),v("h4",An,D(w(g)),1),v("div",Rn,[g.is_current_session&&!e.hoveredCredentialUuid&&!e.hoveredSessionCredentialUuid?(T(),R("span",Tn,"Current")):e.hoveredCredentialUuid===g.credential?(T(),R("span",Mn,"Selected")):e.hoveredSessionCredentialUuid===g.credential?(T(),R("span",Nn,"Linked")):L("",!0),e.allowDelete?(T(),R("button",{key:3,onClick:N=>h.$emit("delete",g),class:"btn-card-delete",disabled:g.is_current_session,title:g.is_current_session?"Cannot delete current session credential":"Delete passkey and terminate any linked sessions.",tabindex:"-1"},"❌",8,Pn)):L("",!0)])]),v("div",Dn,[v("div",Ln,[d[4]||(d[4]=v("span",{class:"date-label"},"Created:",-1)),v("span",qn,D(U(G)(g.created_at)),1),d[5]||(d[5]=v("span",{class:"date-label"},"Last used:",-1)),v("span",Fn,D(U(G)(g.last_used)),1),d[6]||(d[6]=v("span",{class:"date-label"},"Last verified:",-1)),v("span",Un,D(U(G)(g.last_verified)),1)])])],42,En))),128)):(T(),R("div",Sn,[...d[3]||(d[3]=[v("p",null,"No passkeys found.",-1)])]))],32))}},Kn={class:"user-name-heading"},Vn={class:"user-name-row"},Hn=["title"],On={key:0,class:"org-role-sub"},jn={key:0,class:"org-line"},zn={key:1,class:"role-line"},xn={class:"user-details"},$n={class:"date-value"},Jn={class:"date-value"},Yn={class:"date-value"},Qn={key:1,class:"user-info-extra"},Gn={__name:"UserBasicInfo",props:{name:{type:String,required:!0},visits:{type:[Number,String],default:0},createdAt:{type:[String,Number,Date],default:null},lastSeen:{type:[String,Number,Date],default:null},updateEndpoint:{type:String,default:null},canEdit:{type:Boolean,default:!0},loading:{type:Boolean,default:!1},orgDisplayName:{type:String,default:""},roleName:{type:String,default:""}},emits:["saved","editName"],setup(e,{emit:s}){const r=e,t=s;$e();const n=x(()=>!!r.name);return(o,i)=>n.value?(T(),R("div",{key:0,class:se(["user-info",{"has-extra":o.$slots.default}])},[v("h3",Kn,[i[1]||(i[1]=v("span",{class:"icon"},"👤",-1)),v("span",Vn,[v("span",{class:"display-name",title:e.name},D(e.name),9,Hn),e.canEdit&&e.updateEndpoint?(T(),R("button",{key:0,class:"mini-btn",onClick:i[0]||(i[0]=a=>t("editName")),title:"Edit name"},"✏️")):L("",!0)])]),e.orgDisplayName||e.roleName?(T(),R("div",On,[e.orgDisplayName?(T(),R("div",jn,D(e.orgDisplayName),1)):L("",!0),e.roleName?(T(),R("div",zn,D(e.roleName),1)):L("",!0)])):L("",!0),v("div",xn,[i[2]||(i[2]=v("span",{class:"date-label"},[v("strong",null,"Visits:")],-1)),v("span",$n,D(e.visits||0),1),i[3]||(i[3]=v("span",{class:"date-label"},[v("strong",null,"Registered:")],-1)),v("span",Jn,D(U(G)(e.createdAt)),1),i[4]||(i[4]=v("span",{class:"date-label"},[v("strong",null,"Last seen:")],-1)),v("span",Yn,D(U(G)(e.lastSeen)),1)]),o.$slots.default?(T(),R("div",Qn,[Lt(o.$slots,"default",{},void 0)])):L("",!0)],2)):L("",!0)}},_r=Y(Gn,[["__scopeId","data-v-ce373d6c"]]),Wn={__name:"Modal",props:{focusFallback:{type:[HTMLElement,Object],default:null},focusIndex:{type:Number,default:-1},focusSiblingSelector:{type:String,default:""}},emits:["close"],setup(e){const s=e,r=F(null),t=F(null),n=()=>{const i=t.value;if(!i)return;if(document.body.contains(i)&&!i.disabled){i.focus();return}if(s.focusSiblingSelector&&s.focusIndex>=0){const l=[s.focusFallback?.$el||s.focusFallback,i.closest("[data-nav-group]"),i.parentElement?.closest("section"),document.querySelector(".view-root")].filter(Boolean);for(const u of l){if(!u)continue;const f=u.querySelectorAll(s.focusSiblingSelector);if(f.length>0){const w=Math.min(s.focusIndex,f.length-1),b=f[w];if(b&&!b.disabled){b.focus();return}}}}const a=s.focusFallback?.$el||s.focusFallback;if(a&&document.body.contains(a)){const l=a.querySelector?.('button:not([disabled]), a, [tabindex="0"]')||a;if(l?.focus){l.focus();return}}},o=i=>{const a=z(i);if(!a)return;const l=i.target,u=l.closest(".modal-actions");if(u&&(a==="left"||a==="right"))i.preventDefault(),Mt(u,l,a,{itemSelector:"button"});else if(a==="up"&&u){i.preventDefault();const w=(u.closest("form")||u.closest(".modal-form"))?.querySelectorAll("input, textarea, select, button:not(.modal-actions button)");w&&w.length>0&&w[w.length-1].focus()}else if(a==="down"&&!u){const f=l.closest("form")||l.closest(".modal-form");if(f){i.preventDefault();const w=f.querySelector(".modal-actions");w&&sn(w,{primarySelector:".btn-primary",itemSelector:"button"})}}};return qt(()=>{t.value=document.activeElement,ze(()=>{if(r.value){r.value.showModal();const i=r.value.querySelector(".modal-actions .btn-primary");i&&i.setAttribute("data-nav-primary",""),rn(r.value)}})}),Ft(()=>{n()}),(i,a)=>(T(),R("dialog",{ref_key:"dialog",ref:r,onClose:a[0]||(a[0]=l=>i.$emit("close")),onKeydown:o},[Lt(i.$slots,"default",{},void 0)],544))}},kr=Y(Wn,[["__scopeId","data-v-2ebcbb0a"]]),Zn={class:"name-edit-form"},Xn=["for"],eo=["id","type","placeholder","disabled"],to={key:0,class:"error small"},no=["disabled"],oo=["disabled"],ro={__name:"NameEditForm",props:{modelValue:{type:String,default:""},label:{type:String,default:"Name"},placeholder:{type:String,default:""},submitText:{type:String,default:"Save"},cancelText:{type:String,default:"Cancel"},busy:{type:Boolean,default:!1},error:{type:String,default:""},autoFocus:{type:Boolean,default:!0},autoSelect:{type:Boolean,default:!0},inputId:{type:String,default:null},inputType:{type:String,default:"text"}},emits:["update:modelValue","cancel"],setup(e,{emit:s}){const r=e,t=s,n=F(null),o=`name-edit-${Math.random().toString(36).slice(2,10)}`,i=x({get:()=>r.modelValue,set:f=>t("update:modelValue",f)}),a=x(()=>r.inputId||o),l=f=>{if(z(f)==="up"){f.preventDefault(),n.value?.focus();return}};function u(){t("cancel")}return(f,w)=>(T(),R("div",Zn,[v("label",{for:a.value},[xe(D(e.label)+" ",1),an(v("input",{id:a.value,ref_key:"inputRef",ref:n,type:e.inputType,placeholder:e.placeholder,"onUpdate:modelValue":w[0]||(w[0]=b=>i.value=b),disabled:e.busy,required:""},null,8,eo),[[ln,i.value]])],8,Xn),e.error?(T(),R("div",to,D(e.error),1)):L("",!0),v("div",{class:"modal-actions",onKeydown:l},[v("button",{type:"button",class:"btn-secondary",onClick:u,disabled:e.busy},D(e.cancelText),9,no),v("button",{type:"submit",class:"btn-primary",disabled:e.busy,"data-nav-primary":""},D(e.submitText),9,oo)],32)]))}},Br=Y(ro,[["__scopeId","data-v-b73321cf"]]),so={class:"section-block","data-component":"session-list-section"},io={class:"section-header"},ao={class:"section-description"},lo={class:"section-body"},uo=["onKeydown"],co=["href"],fo={class:"session-list"},ho=["onFocusin","onKeydown"],go={class:"item-top"},mo={class:"item-title"},yo={class:"item-actions"},po={key:0,class:"badge badge-current"},wo={key:1,class:"badge badge-current"},bo={key:2,class:"badge badge-current"},vo={key:3,class:"badge"},Co=["onClick","disabled","title"],So={class:"item-details"},Eo={class:"session-dates"},_o={class:"date-label"},ko=["onClick"],Bo={key:1,class:"empty-state"},Ir={__name:"SessionList",props:{sessions:{type:Array,default:()=>[]},emptyMessage:{type:String,default:"You currently have no other active sessions."},sectionDescription:{type:String,default:"Review where you're signed in and end any sessions you no longer recognize."},terminatingSessions:{type:Object,default:()=>({})},hoveredCredentialUuid:{type:String,default:null},navigationDisabled:{type:Boolean,default:!1}},emits:["terminate","sessionHover","navigate-out"],setup(e,{emit:s}){const r=e,t=s,n=$e(),o=F(null),i=F(null),a=c=>{i.value=c,o.value=c.ip||null,t("sessionHover",c)},l=c=>{c.currentTarget.contains(c.relatedTarget)||(i.value=null,o.value=null,t("sessionHover",null))},u=c=>{c.currentTarget.matches(":focus")||(c.currentTarget.focus(),c.stopPropagation())},f=c=>!!r.terminatingSessions[c],w=(c,S)=>{const I=c.currentTarget,p=I.querySelector(".session-list")?.querySelectorAll(".session-item"),y=Array.from(document.querySelectorAll(".session-group")),m=y.indexOf(I);if(c.key==="Enter"&&c.target===I){S&&I.querySelector("a")?.click();return}if(r.navigationDisabled)return;const E=z(c);if(["down","right"].includes(E)&&c.target===I){c.preventDefault(),p?.[0]?.focus();return}if(["up","left"].includes(E)&&c.target===I){c.preventDefault(),m>0?y[m-1].focus():t("navigate-out","up");return}Dt(c,_=>t("navigate-out",_))},b=(c,S)=>{if(Pt(c,()=>{f(S.id)||t("terminate",S)}),c.defaultPrevented||r.navigationDisabled)return;const I=z(c);if(I){c.preventDefault();const C=c.currentTarget.closest(".session-group"),p=C.querySelector(".session-list");if(Nt(p,c.currentTarget,I,{itemSelector:".session-item"})==="boundary"){if(I==="left"||I==="up")C?.focus();else if(I==="down"||I==="right"){const m=Array.from(document.querySelectorAll(".session-group")),E=m.indexOf(C);E<m.length-1?m[E+1].focus():t("navigate-out","down")}}}c.key==="Escape"&&(c.preventDefault(),c.currentTarget.closest(".session-group")?.focus())},h=c=>`${c.includes(":")?"http":"https"}://${c}`,d=async c=>{if(c)try{await navigator.clipboard.writeText(c),n.showMessage("Full IP copied to clipboard!","success",2e3)}catch(S){console.error("Failed to copy IP:",S),n.showMessage("Failed to copy IP","error",3e3)}},g=c=>ae(c)??c,N=x(()=>{if(o.value)return ae(o.value);const c=r.sessions.find(S=>S.is_current);return c?ae(c.ip):null}),A=c=>N.value&&ae(c)===N.value,P=x(()=>{const c={};for(const p of r.sessions){const y=p.host||"";c[y]||(c[y]={sessions:[],isCurrentSite:!1}),c[y].sessions.push(p),p.is_current_host&&(c[y].isCurrentSite=!0)}for(const p in c)c[p].sessions.sort((y,m)=>new Date(m.last_renewed)-new Date(y.last_renewed));const S=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"}),I=Object.keys(c).sort(S.compare),C={};for(const p of I)C[p]=c[p];return C});return(c,S)=>(T(),R("section",so,[v("div",io,[S[2]||(S[2]=v("h2",null,"Active Sessions",-1)),v("p",ao,D(e.sectionDescription),1)]),v("div",lo,[v("div",null,[Array.isArray(e.sessions)&&e.sessions.length?(T(!0),R(oe,{key:0},ce(P.value,(I,C)=>(T(),R("div",{key:C,class:"session-group",tabindex:"0",onKeydown:p=>w(p,C)},[v("span",{class:se(["session-group-host",{"is-current-site":I.isCurrentSite}])},[S[3]||(S[3]=v("span",{class:"session-group-icon"},"🌐",-1)),C?(T(),R("a",{key:0,href:h(C),tabindex:"-1",target:"_blank",rel:"noopener noreferrer"},D(C),9,co)):(T(),R(oe,{key:1},[xe("Unbound host")],64))],2),v("div",fo,[(T(!0),R(oe,null,ce(I.sessions,p=>(T(),R("div",{key:p.id,class:se(["session-item",{"is-current":p.is_current&&!o.value&&!e.hoveredCredentialUuid,"is-hovered":i.value?.id===p.id,"is-linked-credential":e.hoveredCredentialUuid===p.credential}]),tabindex:"-1",onMousedown:S[0]||(S[0]=de(()=>{},["prevent"])),onClickCapture:u,onFocusin:y=>a(p),onFocusout:S[1]||(S[1]=y=>l(y)),onKeydown:y=>b(y,p)},[v("div",go,[v("h4",mo,D(p.user_agent),1),v("div",yo,[p.is_current&&!o.value&&!e.hoveredCredentialUuid?(T(),R("span",po,"Current")):i.value?.id===p.id?(T(),R("span",wo,"Selected")):e.hoveredCredentialUuid===p.credential?(T(),R("span",bo,"Linked")):!e.hoveredCredentialUuid&&A(p.ip)?(T(),R("span",vo,"Same IP")):L("",!0),v("button",{onClick:y=>c.$emit("terminate",p),class:"btn-card-delete",disabled:f(p.id),title:f(p.id)?"Terminating...":"Terminate session",tabindex:"-1"},"❌",8,Co)])]),v("div",So,[v("div",Eo,[v("span",_o,D(U(G)(p.last_renewed)),1),v("span",{class:"date-value",onClick:y=>d(p.ip),title:"Click to copy full IP"},D(g(p.ip)),9,ko)])])],42,ho))),128))])],40,uo))),128)):(T(),R("div",Bo,[v("p",null,D(e.emptyMessage),1)]))])])]))}};function Io(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var te={},we,et;function Ao(){return et||(et=1,we=function(){return typeof Promise=="function"&&Promise.prototype&&Promise.prototype.then}),we}var be={},$={},tt;function W(){if(tt)return $;tt=1;let e;const s=[0,26,44,70,100,134,172,196,242,292,346,404,466,532,581,655,733,815,901,991,1085,1156,1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,2611,2761,2876,3034,3196,3362,3532,3706];return $.getSymbolSize=function(t){if(!t)throw new Error('"version" cannot be null or undefined');if(t<1||t>40)throw new Error('"version" should be in range from 1 to 40');return t*4+17},$.getSymbolTotalCodewords=function(t){return s[t]},$.getBCHDigit=function(r){let t=0;for(;r!==0;)t++,r>>>=1;return t},$.setToSJISFunction=function(t){if(typeof t!="function")throw new Error('"toSJISFunc" is not a valid function.');e=t},$.isKanjiModeEnabled=function(){return typeof e<"u"},$.toSJIS=function(t){return e(t)},$}var ve={},nt;function Je(){return nt||(nt=1,(function(e){e.L={bit:1},e.M={bit:0},e.Q={bit:3},e.H={bit:2};function s(r){if(typeof r!="string")throw new Error("Param is not a string");switch(r.toLowerCase()){case"l":case"low":return e.L;case"m":case"medium":return e.M;case"q":case"quartile":return e.Q;case"h":case"high":return e.H;default:throw new Error("Unknown EC Level: "+r)}}e.isValid=function(t){return t&&typeof t.bit<"u"&&t.bit>=0&&t.bit<4},e.from=function(t,n){if(e.isValid(t))return t;try{return s(t)}catch{return n}}})(ve)),ve}var Ce,ot;function Ro(){if(ot)return Ce;ot=1;function e(){this.buffer=[],this.length=0}return e.prototype={get:function(s){const r=Math.floor(s/8);return(this.buffer[r]>>>7-s%8&1)===1},put:function(s,r){for(let t=0;t<r;t++)this.putBit((s>>>r-t-1&1)===1)},getLengthInBits:function(){return this.length},putBit:function(s){const r=Math.floor(this.length/8);this.buffer.length<=r&&this.buffer.push(0),s&&(this.buffer[r]|=128>>>this.length%8),this.length++}},Ce=e,Ce}var Se,rt;function To(){if(rt)return Se;rt=1;function e(s){if(!s||s<1)throw new Error("BitMatrix size must be defined and greater than 0");this.size=s,this.data=new Uint8Array(s*s),this.reservedBit=new Uint8Array(s*s)}return e.prototype.set=function(s,r,t,n){const o=s*this.size+r;this.data[o]=t,n&&(this.reservedBit[o]=!0)},e.prototype.get=function(s,r){return this.data[s*this.size+r]},e.prototype.xor=function(s,r,t){this.data[s*this.size+r]^=t},e.prototype.isReserved=function(s,r){return this.reservedBit[s*this.size+r]},Se=e,Se}var Ee={},st;function Mo(){return st||(st=1,(function(e){const s=W().getSymbolSize;e.getRowColCoords=function(t){if(t===1)return[];const n=Math.floor(t/7)+2,o=s(t),i=o===145?26:Math.ceil((o-13)/(2*n-2))*2,a=[o-7];for(let l=1;l<n-1;l++)a[l]=a[l-1]-i;return a.push(6),a.reverse()},e.getPositions=function(t){const n=[],o=e.getRowColCoords(t),i=o.length;for(let a=0;a<i;a++)for(let l=0;l<i;l++)a===0&&l===0||a===0&&l===i-1||a===i-1&&l===0||n.push([o[a],o[l]]);return n}})(Ee)),Ee}var _e={},it;function No(){if(it)return _e;it=1;const e=W().getSymbolSize,s=7;return _e.getPositions=function(t){const n=e(t);return[[0,0],[n-s,0],[0,n-s]]},_e}var ke={},at;function Po(){return at||(at=1,(function(e){e.Patterns={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};const s={N1:3,N2:3,N3:40,N4:10};e.isValid=function(n){return n!=null&&n!==""&&!isNaN(n)&&n>=0&&n<=7},e.from=function(n){return e.isValid(n)?parseInt(n,10):void 0},e.getPenaltyN1=function(n){const o=n.size;let i=0,a=0,l=0,u=null,f=null;for(let w=0;w<o;w++){a=l=0,u=f=null;for(let b=0;b<o;b++){let h=n.get(w,b);h===u?a++:(a>=5&&(i+=s.N1+(a-5)),u=h,a=1),h=n.get(b,w),h===f?l++:(l>=5&&(i+=s.N1+(l-5)),f=h,l=1)}a>=5&&(i+=s.N1+(a-5)),l>=5&&(i+=s.N1+(l-5))}return i},e.getPenaltyN2=function(n){const o=n.size;let i=0;for(let a=0;a<o-1;a++)for(let l=0;l<o-1;l++){const u=n.get(a,l)+n.get(a,l+1)+n.get(a+1,l)+n.get(a+1,l+1);(u===4||u===0)&&i++}return i*s.N2},e.getPenaltyN3=function(n){const o=n.size;let i=0,a=0,l=0;for(let u=0;u<o;u++){a=l=0;for(let f=0;f<o;f++)a=a<<1&2047|n.get(u,f),f>=10&&(a===1488||a===93)&&i++,l=l<<1&2047|n.get(f,u),f>=10&&(l===1488||l===93)&&i++}return i*s.N3},e.getPenaltyN4=function(n){let o=0;const i=n.data.length;for(let l=0;l<i;l++)o+=n.data[l];return Math.abs(Math.ceil(o*100/i/5)-10)*s.N4};function r(t,n,o){switch(t){case e.Patterns.PATTERN000:return(n+o)%2===0;case e.Patterns.PATTERN001:return n%2===0;case e.Patterns.PATTERN010:return o%3===0;case e.Patterns.PATTERN011:return(n+o)%3===0;case e.Patterns.PATTERN100:return(Math.floor(n/2)+Math.floor(o/3))%2===0;case e.Patterns.PATTERN101:return n*o%2+n*o%3===0;case e.Patterns.PATTERN110:return(n*o%2+n*o%3)%2===0;case e.Patterns.PATTERN111:return(n*o%3+(n+o)%2)%2===0;default:throw new Error("bad maskPattern:"+t)}}e.applyMask=function(n,o){const i=o.size;for(let a=0;a<i;a++)for(let l=0;l<i;l++)o.isReserved(l,a)||o.xor(l,a,r(n,l,a))},e.getBestMask=function(n,o){const i=Object.keys(e.Patterns).length;let a=0,l=1/0;for(let u=0;u<i;u++){o(u),e.applyMask(u,n);const f=e.getPenaltyN1(n)+e.getPenaltyN2(n)+e.getPenaltyN3(n)+e.getPenaltyN4(n);e.applyMask(u,n),f<l&&(l=f,a=u)}return a}})(ke)),ke}var le={},lt;function Ot(){if(lt)return le;lt=1;const e=Je(),s=[1,1,1,1,1,1,1,1,1,1,2,2,1,2,2,4,1,2,4,4,2,4,4,4,2,4,6,5,2,4,6,6,2,5,8,8,4,5,8,8,4,5,8,11,4,8,10,11,4,9,12,16,4,9,16,16,6,10,12,18,6,10,17,16,6,11,16,19,6,13,18,21,7,14,21,25,8,16,20,25,8,17,23,25,9,17,23,34,9,18,25,30,10,20,27,32,12,21,29,35,12,23,34,37,12,25,34,40,13,26,35,42,14,28,38,45,15,29,40,48,16,31,43,51,17,33,45,54,18,35,48,57,19,37,51,60,19,38,53,63,20,40,56,66,21,43,59,70,22,45,62,74,24,47,65,77,25,49,68,81],r=[7,10,13,17,10,16,22,28,15,26,36,44,20,36,52,64,26,48,72,88,36,64,96,112,40,72,108,130,48,88,132,156,60,110,160,192,72,130,192,224,80,150,224,264,96,176,260,308,104,198,288,352,120,216,320,384,132,240,360,432,144,280,408,480,168,308,448,532,180,338,504,588,196,364,546,650,224,416,600,700,224,442,644,750,252,476,690,816,270,504,750,900,300,560,810,960,312,588,870,1050,336,644,952,1110,360,700,1020,1200,390,728,1050,1260,420,784,1140,1350,450,812,1200,1440,480,868,1290,1530,510,924,1350,1620,540,980,1440,1710,570,1036,1530,1800,570,1064,1590,1890,600,1120,1680,1980,630,1204,1770,2100,660,1260,1860,2220,720,1316,1950,2310,750,1372,2040,2430];return le.getBlocksCount=function(n,o){switch(o){case e.L:return s[(n-1)*4+0];case e.M:return s[(n-1)*4+1];case e.Q:return s[(n-1)*4+2];case e.H:return s[(n-1)*4+3];default:return}},le.getTotalCodewordsCount=function(n,o){switch(o){case e.L:return r[(n-1)*4+0];case e.M:return r[(n-1)*4+1];case e.Q:return r[(n-1)*4+2];case e.H:return r[(n-1)*4+3];default:return}},le}var Be={},ne={},ut;function Do(){if(ut)return ne;ut=1;const e=new Uint8Array(512),s=new Uint8Array(256);return(function(){let t=1;for(let n=0;n<255;n++)e[n]=t,s[t]=n,t<<=1,t&256&&(t^=285);for(let n=255;n<512;n++)e[n]=e[n-255]})(),ne.log=function(t){if(t<1)throw new Error("log("+t+")");return s[t]},ne.exp=function(t){return e[t]},ne.mul=function(t,n){return t===0||n===0?0:e[s[t]+s[n]]},ne}var ct;function Lo(){return ct||(ct=1,(function(e){const s=Do();e.mul=function(t,n){const o=new Uint8Array(t.length+n.length-1);for(let i=0;i<t.length;i++)for(let a=0;a<n.length;a++)o[i+a]^=s.mul(t[i],n[a]);return o},e.mod=function(t,n){let o=new Uint8Array(t);for(;o.length-n.length>=0;){const i=o[0];for(let l=0;l<n.length;l++)o[l]^=s.mul(n[l],i);let a=0;for(;a<o.length&&o[a]===0;)a++;o=o.slice(a)}return o},e.generateECPolynomial=function(t){let n=new Uint8Array([1]);for(let o=0;o<t;o++)n=e.mul(n,new Uint8Array([1,s.exp(o)]));return n}})(Be)),Be}var Ie,dt;function qo(){if(dt)return Ie;dt=1;const e=Lo();function s(r){this.genPoly=void 0,this.degree=r,this.degree&&this.initialize(this.degree)}return s.prototype.initialize=function(t){this.degree=t,this.genPoly=e.generateECPolynomial(this.degree)},s.prototype.encode=function(t){if(!this.genPoly)throw new Error("Encoder not initialized");const n=new Uint8Array(t.length+this.degree);n.set(t);const o=e.mod(n,this.genPoly),i=this.degree-o.length;if(i>0){const a=new Uint8Array(this.degree);return a.set(o,i),a}return o},Ie=s,Ie}var Ae={},Re={},Te={},ft;function jt(){return ft||(ft=1,Te.isValid=function(s){return!isNaN(s)&&s>=1&&s<=40}),Te}var H={},ht;function zt(){if(ht)return H;ht=1;const e="[0-9]+",s="[A-Z $%*+\\-./:]+";let r="(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";r=r.replace(/u/g,"\\u");const t="(?:(?![A-Z0-9 $%*+\\-./:]|"+r+`)(?:.|[\r
2
+ ]))+`;H.KANJI=new RegExp(r,"g"),H.BYTE_KANJI=new RegExp("[^A-Z0-9 $%*+\\-./:]+","g"),H.BYTE=new RegExp(t,"g"),H.NUMERIC=new RegExp(e,"g"),H.ALPHANUMERIC=new RegExp(s,"g");const n=new RegExp("^"+r+"$"),o=new RegExp("^"+e+"$"),i=new RegExp("^[A-Z0-9 $%*+\\-./:]+$");return H.testKanji=function(l){return n.test(l)},H.testNumeric=function(l){return o.test(l)},H.testAlphanumeric=function(l){return i.test(l)},H}var gt;function Z(){return gt||(gt=1,(function(e){const s=jt(),r=zt();e.NUMERIC={id:"Numeric",bit:1,ccBits:[10,12,14]},e.ALPHANUMERIC={id:"Alphanumeric",bit:2,ccBits:[9,11,13]},e.BYTE={id:"Byte",bit:4,ccBits:[8,16,16]},e.KANJI={id:"Kanji",bit:8,ccBits:[8,10,12]},e.MIXED={bit:-1},e.getCharCountIndicator=function(o,i){if(!o.ccBits)throw new Error("Invalid mode: "+o);if(!s.isValid(i))throw new Error("Invalid version: "+i);return i>=1&&i<10?o.ccBits[0]:i<27?o.ccBits[1]:o.ccBits[2]},e.getBestModeForData=function(o){return r.testNumeric(o)?e.NUMERIC:r.testAlphanumeric(o)?e.ALPHANUMERIC:r.testKanji(o)?e.KANJI:e.BYTE},e.toString=function(o){if(o&&o.id)return o.id;throw new Error("Invalid mode")},e.isValid=function(o){return o&&o.bit&&o.ccBits};function t(n){if(typeof n!="string")throw new Error("Param is not a string");switch(n.toLowerCase()){case"numeric":return e.NUMERIC;case"alphanumeric":return e.ALPHANUMERIC;case"kanji":return e.KANJI;case"byte":return e.BYTE;default:throw new Error("Unknown mode: "+n)}}e.from=function(o,i){if(e.isValid(o))return o;try{return t(o)}catch{return i}}})(Re)),Re}var mt;function Fo(){return mt||(mt=1,(function(e){const s=W(),r=Ot(),t=Je(),n=Z(),o=jt(),i=7973,a=s.getBCHDigit(i);function l(b,h,d){for(let g=1;g<=40;g++)if(h<=e.getCapacity(g,d,b))return g}function u(b,h){return n.getCharCountIndicator(b,h)+4}function f(b,h){let d=0;return b.forEach(function(g){const N=u(g.mode,h);d+=N+g.getBitsLength()}),d}function w(b,h){for(let d=1;d<=40;d++)if(f(b,d)<=e.getCapacity(d,h,n.MIXED))return d}e.from=function(h,d){return o.isValid(h)?parseInt(h,10):d},e.getCapacity=function(h,d,g){if(!o.isValid(h))throw new Error("Invalid QR Code version");typeof g>"u"&&(g=n.BYTE);const N=s.getSymbolTotalCodewords(h),A=r.getTotalCodewordsCount(h,d),P=(N-A)*8;if(g===n.MIXED)return P;const c=P-u(g,h);switch(g){case n.NUMERIC:return Math.floor(c/10*3);case n.ALPHANUMERIC:return Math.floor(c/11*2);case n.KANJI:return Math.floor(c/13);case n.BYTE:default:return Math.floor(c/8)}},e.getBestVersionForData=function(h,d){let g;const N=t.from(d,t.M);if(Array.isArray(h)){if(h.length>1)return w(h,N);if(h.length===0)return 1;g=h[0]}else g=h;return l(g.mode,g.getLength(),N)},e.getEncodedBits=function(h){if(!o.isValid(h)||h<7)throw new Error("Invalid QR Code version");let d=h<<12;for(;s.getBCHDigit(d)-a>=0;)d^=i<<s.getBCHDigit(d)-a;return h<<12|d}})(Ae)),Ae}var Me={},yt;function Uo(){if(yt)return Me;yt=1;const e=W(),s=1335,r=21522,t=e.getBCHDigit(s);return Me.getEncodedBits=function(o,i){const a=o.bit<<3|i;let l=a<<10;for(;e.getBCHDigit(l)-t>=0;)l^=s<<e.getBCHDigit(l)-t;return(a<<10|l)^r},Me}var Ne={},Pe,pt;function Ko(){if(pt)return Pe;pt=1;const e=Z();function s(r){this.mode=e.NUMERIC,this.data=r.toString()}return s.getBitsLength=function(t){return 10*Math.floor(t/3)+(t%3?t%3*3+1:0)},s.prototype.getLength=function(){return this.data.length},s.prototype.getBitsLength=function(){return s.getBitsLength(this.data.length)},s.prototype.write=function(t){let n,o,i;for(n=0;n+3<=this.data.length;n+=3)o=this.data.substr(n,3),i=parseInt(o,10),t.put(i,10);const a=this.data.length-n;a>0&&(o=this.data.substr(n),i=parseInt(o,10),t.put(i,a*3+1))},Pe=s,Pe}var De,wt;function Vo(){if(wt)return De;wt=1;const e=Z(),s=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"," ","$","%","*","+","-",".","/",":"];function r(t){this.mode=e.ALPHANUMERIC,this.data=t}return r.getBitsLength=function(n){return 11*Math.floor(n/2)+6*(n%2)},r.prototype.getLength=function(){return this.data.length},r.prototype.getBitsLength=function(){return r.getBitsLength(this.data.length)},r.prototype.write=function(n){let o;for(o=0;o+2<=this.data.length;o+=2){let i=s.indexOf(this.data[o])*45;i+=s.indexOf(this.data[o+1]),n.put(i,11)}this.data.length%2&&n.put(s.indexOf(this.data[o]),6)},De=r,De}var Le,bt;function Ho(){if(bt)return Le;bt=1;const e=Z();function s(r){this.mode=e.BYTE,typeof r=="string"?this.data=new TextEncoder().encode(r):this.data=new Uint8Array(r)}return s.getBitsLength=function(t){return t*8},s.prototype.getLength=function(){return this.data.length},s.prototype.getBitsLength=function(){return s.getBitsLength(this.data.length)},s.prototype.write=function(r){for(let t=0,n=this.data.length;t<n;t++)r.put(this.data[t],8)},Le=s,Le}var qe,vt;function Oo(){if(vt)return qe;vt=1;const e=Z(),s=W();function r(t){this.mode=e.KANJI,this.data=t}return r.getBitsLength=function(n){return n*13},r.prototype.getLength=function(){return this.data.length},r.prototype.getBitsLength=function(){return r.getBitsLength(this.data.length)},r.prototype.write=function(t){let n;for(n=0;n<this.data.length;n++){let o=s.toSJIS(this.data[n]);if(o>=33088&&o<=40956)o-=33088;else if(o>=57408&&o<=60351)o-=49472;else throw new Error("Invalid SJIS character: "+this.data[n]+`
3
+ Make sure your charset is UTF-8`);o=(o>>>8&255)*192+(o&255),t.put(o,13)}},qe=r,qe}var Fe={exports:{}},Ct;function jo(){return Ct||(Ct=1,(function(e){var s={single_source_shortest_paths:function(r,t,n){var o={},i={};i[t]=0;var a=s.PriorityQueue.make();a.push(t,0);for(var l,u,f,w,b,h,d,g,N;!a.empty();){l=a.pop(),u=l.value,w=l.cost,b=r[u]||{};for(f in b)b.hasOwnProperty(f)&&(h=b[f],d=w+h,g=i[f],N=typeof i[f]>"u",(N||g>d)&&(i[f]=d,a.push(f,d),o[f]=u))}if(typeof n<"u"&&typeof i[n]>"u"){var A=["Could not find a path from ",t," to ",n,"."].join("");throw new Error(A)}return o},extract_shortest_path_from_predecessor_list:function(r,t){for(var n=[],o=t;o;)n.push(o),r[o],o=r[o];return n.reverse(),n},find_path:function(r,t,n){var o=s.single_source_shortest_paths(r,t,n);return s.extract_shortest_path_from_predecessor_list(o,n)},PriorityQueue:{make:function(r){var t=s.PriorityQueue,n={},o;r=r||{};for(o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);return n.queue=[],n.sorter=r.sorter||t.default_sorter,n},default_sorter:function(r,t){return r.cost-t.cost},push:function(r,t){var n={value:r,cost:t};this.queue.push(n),this.queue.sort(this.sorter)},pop:function(){return this.queue.shift()},empty:function(){return this.queue.length===0}}};e.exports=s})(Fe)),Fe.exports}var St;function zo(){return St||(St=1,(function(e){const s=Z(),r=Ko(),t=Vo(),n=Ho(),o=Oo(),i=zt(),a=W(),l=jo();function u(A){return unescape(encodeURIComponent(A)).length}function f(A,P,c){const S=[];let I;for(;(I=A.exec(c))!==null;)S.push({data:I[0],index:I.index,mode:P,length:I[0].length});return S}function w(A){const P=f(i.NUMERIC,s.NUMERIC,A),c=f(i.ALPHANUMERIC,s.ALPHANUMERIC,A);let S,I;return a.isKanjiModeEnabled()?(S=f(i.BYTE,s.BYTE,A),I=f(i.KANJI,s.KANJI,A)):(S=f(i.BYTE_KANJI,s.BYTE,A),I=[]),P.concat(c,S,I).sort(function(p,y){return p.index-y.index}).map(function(p){return{data:p.data,mode:p.mode,length:p.length}})}function b(A,P){switch(P){case s.NUMERIC:return r.getBitsLength(A);case s.ALPHANUMERIC:return t.getBitsLength(A);case s.KANJI:return o.getBitsLength(A);case s.BYTE:return n.getBitsLength(A)}}function h(A){return A.reduce(function(P,c){const S=P.length-1>=0?P[P.length-1]:null;return S&&S.mode===c.mode?(P[P.length-1].data+=c.data,P):(P.push(c),P)},[])}function d(A){const P=[];for(let c=0;c<A.length;c++){const S=A[c];switch(S.mode){case s.NUMERIC:P.push([S,{data:S.data,mode:s.ALPHANUMERIC,length:S.length},{data:S.data,mode:s.BYTE,length:S.length}]);break;case s.ALPHANUMERIC:P.push([S,{data:S.data,mode:s.BYTE,length:S.length}]);break;case s.KANJI:P.push([S,{data:S.data,mode:s.BYTE,length:u(S.data)}]);break;case s.BYTE:P.push([{data:S.data,mode:s.BYTE,length:u(S.data)}])}}return P}function g(A,P){const c={},S={start:{}};let I=["start"];for(let C=0;C<A.length;C++){const p=A[C],y=[];for(let m=0;m<p.length;m++){const E=p[m],_=""+C+m;y.push(_),c[_]={node:E,lastCount:0},S[_]={};for(let k=0;k<I.length;k++){const B=I[k];c[B]&&c[B].node.mode===E.mode?(S[B][_]=b(c[B].lastCount+E.length,E.mode)-b(c[B].lastCount,E.mode),c[B].lastCount+=E.length):(c[B]&&(c[B].lastCount=E.length),S[B][_]=b(E.length,E.mode)+4+s.getCharCountIndicator(E.mode,P))}}I=y}for(let C=0;C<I.length;C++)S[I[C]].end=0;return{map:S,table:c}}function N(A,P){let c;const S=s.getBestModeForData(A);if(c=s.from(P,S),c!==s.BYTE&&c.bit<S.bit)throw new Error('"'+A+'" cannot be encoded with mode '+s.toString(c)+`.
4
+ Suggested mode is: `+s.toString(S));switch(c===s.KANJI&&!a.isKanjiModeEnabled()&&(c=s.BYTE),c){case s.NUMERIC:return new r(A);case s.ALPHANUMERIC:return new t(A);case s.KANJI:return new o(A);case s.BYTE:return new n(A)}}e.fromArray=function(P){return P.reduce(function(c,S){return typeof S=="string"?c.push(N(S,null)):S.data&&c.push(N(S.data,S.mode)),c},[])},e.fromString=function(P,c){const S=w(P,a.isKanjiModeEnabled()),I=d(S),C=g(I,c),p=l.find_path(C.map,"start","end"),y=[];for(let m=1;m<p.length-1;m++)y.push(C.table[p[m]].node);return e.fromArray(h(y))},e.rawSplit=function(P){return e.fromArray(w(P,a.isKanjiModeEnabled()))}})(Ne)),Ne}var Et;function xo(){if(Et)return be;Et=1;const e=W(),s=Je(),r=Ro(),t=To(),n=Mo(),o=No(),i=Po(),a=Ot(),l=qo(),u=Fo(),f=Uo(),w=Z(),b=zo();function h(C,p){const y=C.size,m=o.getPositions(p);for(let E=0;E<m.length;E++){const _=m[E][0],k=m[E][1];for(let B=-1;B<=7;B++)if(!(_+B<=-1||y<=_+B))for(let M=-1;M<=7;M++)k+M<=-1||y<=k+M||(B>=0&&B<=6&&(M===0||M===6)||M>=0&&M<=6&&(B===0||B===6)||B>=2&&B<=4&&M>=2&&M<=4?C.set(_+B,k+M,!0,!0):C.set(_+B,k+M,!1,!0))}}function d(C){const p=C.size;for(let y=8;y<p-8;y++){const m=y%2===0;C.set(y,6,m,!0),C.set(6,y,m,!0)}}function g(C,p){const y=n.getPositions(p);for(let m=0;m<y.length;m++){const E=y[m][0],_=y[m][1];for(let k=-2;k<=2;k++)for(let B=-2;B<=2;B++)k===-2||k===2||B===-2||B===2||k===0&&B===0?C.set(E+k,_+B,!0,!0):C.set(E+k,_+B,!1,!0)}}function N(C,p){const y=C.size,m=u.getEncodedBits(p);let E,_,k;for(let B=0;B<18;B++)E=Math.floor(B/3),_=B%3+y-8-3,k=(m>>B&1)===1,C.set(E,_,k,!0),C.set(_,E,k,!0)}function A(C,p,y){const m=C.size,E=f.getEncodedBits(p,y);let _,k;for(_=0;_<15;_++)k=(E>>_&1)===1,_<6?C.set(_,8,k,!0):_<8?C.set(_+1,8,k,!0):C.set(m-15+_,8,k,!0),_<8?C.set(8,m-_-1,k,!0):_<9?C.set(8,15-_-1+1,k,!0):C.set(8,15-_-1,k,!0);C.set(m-8,8,1,!0)}function P(C,p){const y=C.size;let m=-1,E=y-1,_=7,k=0;for(let B=y-1;B>0;B-=2)for(B===6&&B--;;){for(let M=0;M<2;M++)if(!C.isReserved(E,B-M)){let V=!1;k<p.length&&(V=(p[k]>>>_&1)===1),C.set(E,B-M,V),_--,_===-1&&(k++,_=7)}if(E+=m,E<0||y<=E){E-=m,m=-m;break}}}function c(C,p,y){const m=new r;y.forEach(function(M){m.put(M.mode.bit,4),m.put(M.getLength(),w.getCharCountIndicator(M.mode,C)),M.write(m)});const E=e.getSymbolTotalCodewords(C),_=a.getTotalCodewordsCount(C,p),k=(E-_)*8;for(m.getLengthInBits()+4<=k&&m.put(0,4);m.getLengthInBits()%8!==0;)m.putBit(0);const B=(k-m.getLengthInBits())/8;for(let M=0;M<B;M++)m.put(M%2?17:236,8);return S(m,C,p)}function S(C,p,y){const m=e.getSymbolTotalCodewords(p),E=a.getTotalCodewordsCount(p,y),_=m-E,k=a.getBlocksCount(p,y),B=m%k,M=k-B,V=Math.floor(m/k),K=Math.floor(_/k),q=K+1,Ye=V-K,$t=new l(Ye);let he=0;const ie=new Array(k),Qe=new Array(k);let ge=0;const Jt=new Uint8Array(C.buffer);for(let X=0;X<k;X++){const ye=X<M?K:q;ie[X]=Jt.slice(he,he+ye),Qe[X]=$t.encode(ie[X]),he+=ye,ge=Math.max(ge,ye)}const me=new Uint8Array(m);let Ge=0,O,j;for(O=0;O<ge;O++)for(j=0;j<k;j++)O<ie[j].length&&(me[Ge++]=ie[j][O]);for(O=0;O<Ye;O++)for(j=0;j<k;j++)me[Ge++]=Qe[j][O];return me}function I(C,p,y,m){let E;if(Array.isArray(C))E=b.fromArray(C);else if(typeof C=="string"){let V=p;if(!V){const K=b.rawSplit(C);V=u.getBestVersionForData(K,y)}E=b.fromString(C,V||40)}else throw new Error("Invalid data");const _=u.getBestVersionForData(E,y);if(!_)throw new Error("The amount of data is too big to be stored in a QR Code");if(!p)p=_;else if(p<_)throw new Error(`
5
+ The chosen QR Code version cannot contain this amount of data.
6
+ Minimum version required to store current data is: `+_+`.
7
+ `);const k=c(p,y,E),B=e.getSymbolSize(p),M=new t(B);return h(M,p),d(M),g(M,p),A(M,y,0),p>=7&&N(M,p),P(M,k),isNaN(m)&&(m=i.getBestMask(M,A.bind(null,M,y))),i.applyMask(m,M),A(M,y,m),{modules:M,version:p,errorCorrectionLevel:y,maskPattern:m,segments:E}}return be.create=function(p,y){if(typeof p>"u"||p==="")throw new Error("No input text");let m=s.M,E,_;return typeof y<"u"&&(m=s.from(y.errorCorrectionLevel,s.M),E=u.from(y.version),_=i.from(y.maskPattern),y.toSJISFunc&&e.setToSJISFunction(y.toSJISFunc)),I(p,E,m,_)},be}var Ue={},Ke={},_t;function xt(){return _t||(_t=1,(function(e){function s(r){if(typeof r=="number"&&(r=r.toString()),typeof r!="string")throw new Error("Color should be defined as hex string");let t=r.slice().replace("#","").split("");if(t.length<3||t.length===5||t.length>8)throw new Error("Invalid hex color: "+r);(t.length===3||t.length===4)&&(t=Array.prototype.concat.apply([],t.map(function(o){return[o,o]}))),t.length===6&&t.push("F","F");const n=parseInt(t.join(""),16);return{r:n>>24&255,g:n>>16&255,b:n>>8&255,a:n&255,hex:"#"+t.slice(0,6).join("")}}e.getOptions=function(t){t||(t={}),t.color||(t.color={});const n=typeof t.margin>"u"||t.margin===null||t.margin<0?4:t.margin,o=t.width&&t.width>=21?t.width:void 0,i=t.scale||4;return{width:o,scale:o?4:i,margin:n,color:{dark:s(t.color.dark||"#000000ff"),light:s(t.color.light||"#ffffffff")},type:t.type,rendererOpts:t.rendererOpts||{}}},e.getScale=function(t,n){return n.width&&n.width>=t+n.margin*2?n.width/(t+n.margin*2):n.scale},e.getImageWidth=function(t,n){const o=e.getScale(t,n);return Math.floor((t+n.margin*2)*o)},e.qrToImageData=function(t,n,o){const i=n.modules.size,a=n.modules.data,l=e.getScale(i,o),u=Math.floor((i+o.margin*2)*l),f=o.margin*l,w=[o.color.light,o.color.dark];for(let b=0;b<u;b++)for(let h=0;h<u;h++){let d=(b*u+h)*4,g=o.color.light;if(b>=f&&h>=f&&b<u-f&&h<u-f){const N=Math.floor((b-f)/l),A=Math.floor((h-f)/l);g=w[a[N*i+A]?1:0]}t[d++]=g.r,t[d++]=g.g,t[d++]=g.b,t[d]=g.a}}})(Ke)),Ke}var kt;function $o(){return kt||(kt=1,(function(e){const s=xt();function r(n,o,i){n.clearRect(0,0,o.width,o.height),o.style||(o.style={}),o.height=i,o.width=i,o.style.height=i+"px",o.style.width=i+"px"}function t(){try{return document.createElement("canvas")}catch{throw new Error("You need to specify a canvas element")}}e.render=function(o,i,a){let l=a,u=i;typeof l>"u"&&(!i||!i.getContext)&&(l=i,i=void 0),i||(u=t()),l=s.getOptions(l);const f=s.getImageWidth(o.modules.size,l),w=u.getContext("2d"),b=w.createImageData(f,f);return s.qrToImageData(b.data,o,l),r(w,u,f),w.putImageData(b,0,0),u},e.renderToDataURL=function(o,i,a){let l=a;typeof l>"u"&&(!i||!i.getContext)&&(l=i,i=void 0),l||(l={});const u=e.render(o,i,l),f=l.type||"image/png",w=l.rendererOpts||{};return u.toDataURL(f,w.quality)}})(Ue)),Ue}var Ve={},Bt;function Jo(){if(Bt)return Ve;Bt=1;const e=xt();function s(n,o){const i=n.a/255,a=o+'="'+n.hex+'"';return i<1?a+" "+o+'-opacity="'+i.toFixed(2).slice(1)+'"':a}function r(n,o,i){let a=n+o;return typeof i<"u"&&(a+=" "+i),a}function t(n,o,i){let a="",l=0,u=!1,f=0;for(let w=0;w<n.length;w++){const b=Math.floor(w%o),h=Math.floor(w/o);!b&&!u&&(u=!0),n[w]?(f++,w>0&&b>0&&n[w-1]||(a+=u?r("M",b+i,.5+h+i):r("m",l,0),l=0,u=!1),b+1<o&&n[w+1]||(a+=r("h",f),f=0)):l++}return a}return Ve.render=function(o,i,a){const l=e.getOptions(i),u=o.modules.size,f=o.modules.data,w=u+l.margin*2,b=l.color.light.a?"<path "+s(l.color.light,"fill")+' d="M0 0h'+w+"v"+w+'H0z"/>':"",h="<path "+s(l.color.dark,"stroke")+' d="'+t(f,u,l.margin)+'"/>',d='viewBox="0 0 '+w+" "+w+'"',N='<svg xmlns="http://www.w3.org/2000/svg" '+(l.width?'width="'+l.width+'" height="'+l.width+'" ':"")+d+' shape-rendering="crispEdges">'+b+h+`</svg>
8
+ `;return typeof a=="function"&&a(null,N),N},Ve}var It;function Yo(){if(It)return te;It=1;const e=Ao(),s=xo(),r=$o(),t=Jo();function n(o,i,a,l,u){const f=[].slice.call(arguments,1),w=f.length,b=typeof f[w-1]=="function";if(!b&&!e())throw new Error("Callback required as last argument");if(b){if(w<2)throw new Error("Too few arguments provided");w===2?(u=a,a=i,i=l=void 0):w===3&&(i.getContext&&typeof u>"u"?(u=l,l=void 0):(u=l,l=a,a=i,i=void 0))}else{if(w<1)throw new Error("Too few arguments provided");return w===1?(a=i,i=l=void 0):w===2&&!i.getContext&&(l=a,a=i,i=void 0),new Promise(function(h,d){try{const g=s.create(a,l);h(o(g,i,l))}catch(g){d(g)}})}try{const h=s.create(a,l);u(null,o(h,i,l))}catch(h){u(h)}}return te.create=s.create,te.toCanvas=n.bind(null,r.render),te.toDataURL=n.bind(null,r.renderToDataURL),te.toString=n.bind(null,function(o,i,a){return t.render(o,a)}),te}var Qo=Yo();const Go=Io(Qo),Wo={class:"qr-display"},Zo={class:"qr-section"},Xo=["href","onKeydown"],er={key:0,class:"link-text"},tr={__name:"QRCodeDisplay",props:{url:{type:String,required:!0},showLink:{type:Boolean,default:!1}},emits:["copied"],setup(e,{emit:s}){const r=e,t=s,n=F(null),o=x(()=>r.url?r.url.replace(/^https?:\/\//,""):"");function i(){if(!(!r.url||!n.value))try{n.value.getContext("2d").clearRect(0,0,n.value.width,n.value.height),Go.toCanvas(n.value,r.url,{scale:6,margin:0,color:{dark:"#000000",light:"#FFFFFF"}}),n.value.removeAttribute("style")}catch(l){console.error("QR code generation failed:",l)}}async function a(){if(r.url)try{await navigator.clipboard.writeText(r.url),t("copied")}catch(l){console.error("Failed to copy link:",l)}}return He(()=>r.url,()=>{i()},{immediate:!0}),He(n,()=>{n.value&&r.url&&i()},{immediate:!0}),(l,u)=>(T(),R("div",Wo,[v("div",Zo,[v("a",{href:e.url,onClick:de(a,["prevent"]),class:"qr-link",title:"Click to copy link",tabindex:"0",onKeydown:un(de(a,["prevent"]),["enter"])},[v("canvas",{ref_key:"qrCanvas",ref:n,class:"qr-code"},null,512),e.showLink&&e.url?(T(),R("div",er,D(o.value),1)):L("",!0)],40,Xo)])]))}},nr=Y(tr,[["__scopeId","data-v-727427c4"]]),or={class:"device-dialog",role:"dialog","aria-modal":"true","aria-labelledby":"regTitle"},rr={class:"reg-header-row"},sr={id:"regTitle",class:"reg-title"},ir={key:0},ar={key:1},lr={class:"device-link-section"},ur={key:0,class:"expiry-note"},cr={__name:"RegistrationLinkModal",props:{endpoint:{type:String,required:!0},userName:{type:String,default:""}},emits:["close","copied"],setup(e,{emit:s}){const r=e,t=s,n=F(null),o=F(null),i=F(null),a=F(null),l=F(null);async function u(){try{const d=await Q(r.endpoint,{method:"POST"});if(d.url){if(o.value=d.url,i.value=d.expires?new Date(d.expires):null,await ze(),n.value){n.value.showModal();const g=a.value;(g?.querySelector(".btn-primary")||g?.querySelector("button"))?.focus()}}else t("close")}catch{t("close")}}function f(){t("copied")}const w=d=>{const g=z(d)},b=d=>{const g=z(d);g&&(d.preventDefault(),(g==="down"||g==="up")&&a.value?.querySelector("button")?.focus())},h=d=>{const g=z(d);g&&(d.preventDefault(),(g==="up"||g==="down")&&document.querySelector(".qr-link")?.focus())};return qt(()=>{l.value=document.activeElement,u()}),Ft(()=>{const d=l.value;d&&document.body.contains(d)&&!d.disabled&&d.focus()}),(d,g)=>(T(),R("dialog",{ref_key:"dialog",ref:n,onClose:g[2]||(g[2]=N=>d.$emit("close")),onKeydown:w},[v("div",or,[v("div",rr,[v("h2",sr,[g[3]||(g[3]=xe(" 📱 ",-1)),e.userName?(T(),R("span",ir,"Registration for "+D(e.userName),1)):(T(),R("span",ar,"Add Another Device"))]),v("button",{class:"icon-btn",onClick:g[0]||(g[0]=N=>d.$emit("close")),"aria-label":"Close",tabindex:"-1"},"✕")]),v("div",lr,[g[4]||(g[4]=v("p",{class:"reg-help"}," Scan this QR code on the new device, or copy the link and open it there. ",-1)),cn(nr,{url:o.value,"show-link":!0,onCopied:f,onKeydown:b},null,8,["url"]),i.value?(T(),R("p",ur," This link expires "+D(U(G)(i.value).toLowerCase())+". ",1)):L("",!0)]),v("div",{class:"reg-actions",ref_key:"actionsRow",ref:a,onKeydown:h},[v("button",{class:"btn-secondary",onClick:g[1]||(g[1]=N=>d.$emit("close"))},"Close")],544)])],544))}},Ar=Y(cr,[["__scopeId","data-v-e04dd463"]]),dr={class:"loading-container"},fr={__name:"LoadingView",props:{message:{type:String,default:"Loading..."}},setup(e){return(s,r)=>(T(),R("div",dr,[r[0]||(r[0]=v("div",{class:"loading-spinner"},null,-1)),v("p",null,D(e.message),1)]))}},Rr=Y(fr,[["__scopeId","data-v-130f5abf"]]),hr={class:"message-container"},gr={class:"message-content"},mr={key:0,class:"error-detail"},yr={class:"button-row"},pr={__name:"AccessDenied",props:{title:{type:String,default:"Access Denied"},icon:{type:String,default:"🔒"},message:{type:String,default:null}},setup(e){function s(){window.location.reload()}return(r,t)=>(T(),R("div",hr,[v("div",gr,[v("h2",null,D(e.icon)+" "+D(e.title),1),e.message?(T(),R("p",mr,D(e.message),1)):L("",!0),v("div",yr,[v("button",{class:"btn-secondary",onClick:t[0]||(t[0]=(...n)=>U(We)&&U(We)(...n))},"Back"),v("button",{class:"btn-primary",onClick:s},"Reload Page")])])]))}},Tr=Y(pr,[["__scopeId","data-v-a7b258e7"]]);export{Tr as A,Sr as B,Rr as L,kr as M,Br as N,Ar as R,_r as U,Er as _,Ir as a,Cr as b,vr as c,$e as u};
@@ -1 +1 @@
1
- .remote-auth-inline[data-v-1280e25b]{display:flex;flex-direction:column;gap:1rem;width:100%}.loading-section[data-v-1280e25b]{display:flex;flex-direction:column;align-items:center;gap:.75rem;padding:2rem 1rem;min-height:180px;justify-content:center}.loading-section p[data-v-1280e25b]{margin:0;color:var(--color-text-muted);font-size:.95rem}.spinner[data-v-1280e25b]{width:40px;height:40px;border:3px solid var(--color-border);border-top-color:var(--color-primary);border-radius:50%;animation:spin-1280e25b .8s linear infinite}@keyframes spin-1280e25b{to{transform:rotate(360deg)}}.auth-display[data-v-1280e25b]{display:flex;flex-direction:column;gap:1.25rem;width:100%;min-height:180px}.auth-content[data-v-1280e25b]{display:flex;gap:2rem;align-items:center;justify-content:center;flex-wrap:nowrap}.loading-placeholder[data-v-1280e25b]{display:flex;flex-direction:column;align-items:center;gap:.75rem;width:100%;padding:1rem}.loading-placeholder p[data-v-1280e25b]{margin:0;color:var(--color-text-muted);font-size:.95rem}.pairing-code-section[data-v-1280e25b]{flex:0 0 auto;display:flex;flex-direction:column;gap:.5rem;width:280px;max-width:100%}.pairing-label[data-v-1280e25b]{margin:0;font-size:.875rem;color:var(--color-text-muted);font-weight:500;text-align:center}.slot-machine[data-v-1280e25b]{padding:.875rem 1rem;background:var(--color-surface-hover, rgba(0, 0, 0, .03));border:2px solid var(--color-border);border-radius:var(--radius-sm, 6px);font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;display:flex;align-items:center;-webkit-user-select:none;user-select:none;pointer-events:none;white-space:nowrap;overflow:hidden}.slot-reel[data-v-1280e25b]{overflow:hidden;background:var(--color-surface, rgba(255, 255, 255, .5))}.slot-machine:not(.stopped) .slot-reel[data-v-1280e25b]:nth-child(1){animation:slotSpin-1280e25b .14s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel[data-v-1280e25b]:nth-child(2){animation:slotSpin-1280e25b .17s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel[data-v-1280e25b]:nth-child(3){animation:slotSpin-1280e25b .2s ease-in-out infinite}.slot-word[data-v-1280e25b]{font-size:1.25rem;font-weight:600;letter-spacing:.05em;text-align:center;width:100%}.slot-machine:not(.stopped) .slot-reel:nth-child(1) .slot-word[data-v-1280e25b]{animation:wordRoll-1280e25b .14s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel:nth-child(2) .slot-word[data-v-1280e25b]{animation:wordRoll-1280e25b .17s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel:nth-child(3) .slot-word[data-v-1280e25b]{animation:wordRoll-1280e25b .2s ease-in-out infinite}@keyframes slotSpin-1280e25b{0%{box-shadow:inset 0 2px 4px #0000001a}50%{box-shadow:inset 0 4px 8px #0003}to{box-shadow:inset 0 2px 4px #0000001a}}@keyframes wordRoll-1280e25b{0%{transform:translateY(-30%) scale(.9);opacity:.4;filter:blur(1.5px)}25%{transform:translateY(-10%) scale(.95);opacity:.6;filter:blur(1px)}50%{transform:translateY(0) scale(1);opacity:1;filter:blur(0)}75%{transform:translateY(10%) scale(.95);opacity:.6;filter:blur(1px)}to{transform:translateY(30%) scale(.9);opacity:.4;filter:blur(1.5px)}}.site-url[data-v-1280e25b]{margin:.5rem 0 0;font-size:.8rem;color:var(--color-text-muted);text-align:center;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;opacity:.8}.waiting-indicator[data-v-1280e25b]{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem;background:var(--color-surface-hover, rgba(0, 0, 0, .02));border-radius:var(--radius-sm, 6px);font-size:.875rem;color:var(--color-text-muted)}.spinner-small[data-v-1280e25b]{width:16px;height:16px;border:2px solid var(--color-border);border-top-color:var(--color-primary);border-radius:50%;animation:spin-1280e25b .8s linear infinite}.success-section[data-v-1280e25b]{padding:1rem;text-align:center;min-height:180px;display:flex;align-items:center;justify-content:center}.success-message[data-v-1280e25b]{margin:0;font-size:1rem;color:var(--color-success, #10b981);font-weight:500}.error-section[data-v-1280e25b]{padding:1rem;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;min-height:180px}.error-message[data-v-1280e25b]{margin:0;font-size:.95rem;color:var(--color-error, #ef4444)}@media(max-width:640px){.auth-content[data-v-1280e25b]{gap:1.5rem;flex-direction:column;align-items:center}.pairing-code-section[data-v-1280e25b]{width:100%;max-width:280px}}@media(max-width:480px){.pairing-code[data-v-1280e25b]{font-size:1.1rem;padding:.75rem .875rem}.pairing-code-section[data-v-1280e25b]{width:100%;max-width:100%}}.button-row.center[data-v-0a5d98ce]{display:flex;justify-content:center;gap:.75rem;flex-wrap:wrap}.user-line[data-v-0a5d98ce]{margin:.5rem 0 0;font-weight:500;color:var(--color-text)}main.view-root[data-v-0a5d98ce]{min-height:100vh;align-items:center;justify-content:center;padding:2rem 1rem}.surface.surface--tight[data-v-0a5d98ce]{max-width:520px;margin:0 auto;width:100%;display:flex;flex-direction:column;gap:1.75rem}.auth-view[data-v-0a5d98ce]{display:flex;flex-direction:column;align-items:center;gap:1rem;width:100%}.view-lede[data-v-0a5d98ce] .inline-link{color:var(--color-primary);text-decoration:none;transition:opacity .15s;font-weight:400}.view-lede[data-v-0a5d98ce] .inline-link:hover{opacity:.8;text-decoration:underline}
1
+ .remote-auth-inline[data-v-1280e25b]{display:flex;flex-direction:column;gap:1rem;width:100%}.loading-section[data-v-1280e25b]{display:flex;flex-direction:column;align-items:center;gap:.75rem;padding:2rem 1rem;min-height:180px;justify-content:center}.loading-section p[data-v-1280e25b]{margin:0;color:var(--color-text-muted);font-size:.95rem}.spinner[data-v-1280e25b]{width:40px;height:40px;border:3px solid var(--color-border);border-top-color:var(--color-primary);border-radius:50%;animation:spin-1280e25b .8s linear infinite}@keyframes spin-1280e25b{to{transform:rotate(360deg)}}.auth-display[data-v-1280e25b]{display:flex;flex-direction:column;gap:1.25rem;width:100%;min-height:180px}.auth-content[data-v-1280e25b]{display:flex;gap:2rem;align-items:center;justify-content:center;flex-wrap:nowrap}.loading-placeholder[data-v-1280e25b]{display:flex;flex-direction:column;align-items:center;gap:.75rem;width:100%;padding:1rem}.loading-placeholder p[data-v-1280e25b]{margin:0;color:var(--color-text-muted);font-size:.95rem}.pairing-code-section[data-v-1280e25b]{flex:0 0 auto;display:flex;flex-direction:column;gap:.5rem;width:280px;max-width:100%}.pairing-label[data-v-1280e25b]{margin:0;font-size:.875rem;color:var(--color-text-muted);font-weight:500;text-align:center}.slot-machine[data-v-1280e25b]{padding:.875rem 1rem;background:var(--color-surface-hover, rgba(0, 0, 0, .03));border:2px solid var(--color-border);border-radius:var(--radius-sm, 6px);font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;display:flex;align-items:center;-webkit-user-select:none;user-select:none;pointer-events:none;white-space:nowrap;overflow:hidden}.slot-reel[data-v-1280e25b]{overflow:hidden;background:var(--color-surface, rgba(255, 255, 255, .5))}.slot-machine:not(.stopped) .slot-reel[data-v-1280e25b]:nth-child(1){animation:slotSpin-1280e25b .14s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel[data-v-1280e25b]:nth-child(2){animation:slotSpin-1280e25b .17s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel[data-v-1280e25b]:nth-child(3){animation:slotSpin-1280e25b .2s ease-in-out infinite}.slot-word[data-v-1280e25b]{font-size:1.25rem;font-weight:600;letter-spacing:.05em;text-align:center;width:100%}.slot-machine:not(.stopped) .slot-reel:nth-child(1) .slot-word[data-v-1280e25b]{animation:wordRoll-1280e25b .14s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel:nth-child(2) .slot-word[data-v-1280e25b]{animation:wordRoll-1280e25b .17s ease-in-out infinite}.slot-machine:not(.stopped) .slot-reel:nth-child(3) .slot-word[data-v-1280e25b]{animation:wordRoll-1280e25b .2s ease-in-out infinite}@keyframes slotSpin-1280e25b{0%{box-shadow:inset 0 2px 4px #0000001a}50%{box-shadow:inset 0 4px 8px #0003}to{box-shadow:inset 0 2px 4px #0000001a}}@keyframes wordRoll-1280e25b{0%{transform:translateY(-30%) scale(.9);opacity:.4;filter:blur(1.5px)}25%{transform:translateY(-10%) scale(.95);opacity:.6;filter:blur(1px)}50%{transform:translateY(0) scale(1);opacity:1;filter:blur(0)}75%{transform:translateY(10%) scale(.95);opacity:.6;filter:blur(1px)}to{transform:translateY(30%) scale(.9);opacity:.4;filter:blur(1.5px)}}.site-url[data-v-1280e25b]{margin:.5rem 0 0;font-size:.8rem;color:var(--color-text-muted);text-align:center;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;opacity:.8}.waiting-indicator[data-v-1280e25b]{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem;background:var(--color-surface-hover, rgba(0, 0, 0, .02));border-radius:var(--radius-sm, 6px);font-size:.875rem;color:var(--color-text-muted)}.spinner-small[data-v-1280e25b]{width:16px;height:16px;border:2px solid var(--color-border);border-top-color:var(--color-primary);border-radius:50%;animation:spin-1280e25b .8s linear infinite}.success-section[data-v-1280e25b]{padding:1rem;text-align:center;min-height:180px;display:flex;align-items:center;justify-content:center}.success-message[data-v-1280e25b]{margin:0;font-size:1rem;color:var(--color-success, #10b981);font-weight:500}.error-section[data-v-1280e25b]{padding:1rem;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;min-height:180px}.error-message[data-v-1280e25b]{margin:0;font-size:.95rem;color:var(--color-error, #ef4444)}@media(max-width:640px){.auth-content[data-v-1280e25b]{gap:1.5rem;flex-direction:column;align-items:center}.pairing-code-section[data-v-1280e25b]{width:100%;max-width:280px}}@media(max-width:480px){.pairing-code[data-v-1280e25b]{font-size:1.1rem;padding:.75rem .875rem}.pairing-code-section[data-v-1280e25b]{width:100%;max-width:100%}}.button-row.center[data-v-5c04d110]{display:flex;justify-content:center;gap:.75rem;flex-wrap:wrap}.user-line[data-v-5c04d110]{margin:.5rem 0 0;font-weight:500;color:var(--color-text)}main.view-root[data-v-5c04d110]{min-height:100vh;align-items:center;justify-content:center;padding:2rem 1rem}.surface.surface--tight[data-v-5c04d110]{max-width:520px;margin:0 auto;width:100%;display:flex;flex-direction:column;gap:1.75rem}.auth-view[data-v-5c04d110]{display:flex;flex-direction:column;align-items:center;gap:1rem;width:100%}.view-lede[data-v-5c04d110] .inline-link{color:var(--color-primary);text-decoration:none;transition:opacity .15s;font-weight:400}.view-lede[data-v-5c04d110] .inline-link:hover{opacity:.8;text-decoration:underline}
@@ -0,0 +1 @@
1
+ import{_ as G,r as m,c as S,w as Y,o as J,a as K,b as i,d as l,e as t,t as _,F as N,i as j,f as P,m as Q,p as Z,O as ee,g as te,a1 as se,x as ae,a7 as O,a6 as H,G as ne,n as oe,a8 as ie,a4 as le}from"./_plugin-vue_export-helper-nhjnO_bd.js";import{c as re,s as ce,b as ue,w as z}from"./pow-2N9bxgAo.js";const de={class:"remote-auth-inline"},he={key:0,class:"success-section"},ve={class:"success-message"},fe={key:1,class:"error-section"},me={class:"error-message"},ge={key:2,class:"auth-display"},pe={class:"auth-content"},_e={class:"pairing-code-section"},we={class:"slot-machine","aria-hidden":"true"},ye={class:"slot-word"},ke={class:"site-url"},be={key:3,class:"auth-display"},$e={class:"auth-content"},Ae={key:0,class:"pairing-code-section"},Re={class:"slot-machine stopped"},Se={class:"slot-word"},Ce={class:"site-url"},Pe={class:"waiting-indicator"},Te={__name:"RemoteAuthRequest",props:{active:{type:Boolean,default:!1}},emits:["authenticated","cancelled","error","register"],setup(w,{expose:I,emit:x}){const $=w,g=x,v=m(null),y=m(!1),n=m(null),A=m("connecting"),p=m(null),u=m(["","",""]);let a=null,k=null;const W=S(()=>v.value?v.value.replace(/\./g," "):""),b=S(()=>{if(!p.value)return"";const s=(p.value.auth_site_url||`${location.protocol}//${location.host}/auth/`).replace(/^https?:\/\//,"");return s.endsWith("/")?s.slice(0,-1):s}),E=S(()=>A.value==="authenticating"?"Complete on another device…":"Waiting for authentication…"),B=S(()=>"Authenticated successfully!");function C(){return z[Math.floor(Math.random()*z.length)]}function F(){u.value=[C(),C(),C()];const c=20,s=[setInterval(()=>{const o=[...u.value];o[0]=C(),u.value=o},140),setInterval(()=>{const o=[...u.value];o[1]=C(),u.value=o},170),setInterval(()=>{const o=[...u.value];o[2]=C(),u.value=o},200)];k=s,setTimeout(()=>{s.forEach(o=>clearInterval(o)),k=null},c*170)}function f(){k&&(Array.isArray(k)?k.forEach(c=>clearInterval(c)):clearInterval(k),k=null)}async function L(){n.value=null,y.value=!1,v.value=null,A.value="connecting",F();try{p.value=await Q();const c=p.value?.auth_host,s="/auth/ws/remote-auth/request",o=c&&location.host!==c?`//${c}${s}`:s;a=await Z(o);const R=await a.receive_json();if(R.pow){const h=re(R.pow.challenge),V=await ce(h,R.pow.work);a.send_json({pow:ue(V),action:"login"})}const T=await a.receive_json();if(T.status)throw new Error(T.detail||`Failed to create remote auth request: ${T.status}`);for(v.value=T.pairing_code,f(),A.value="waiting";;){const h=await a.receive_json();if(h.status==="locked")A.value="authenticating";else if(h.status==="paired")A.value="authenticating";else if(h.status==="authenticated"){y.value=!0,g("authenticated",{session_token:h.session_token});break}else{if(h.status==="denied")throw new Error("Access denied");if(h.status==="completed"){h.reset_token&&(y.value=!0,g("register",h.reset_token));break}else if(h.status==="error"||h.detail)throw new Error(h.detail||"Remote authentication failed")}}}catch(c){console.error("Remote authentication error:",c);const s=c.message||"Authentication failed";n.value=s,g("error",s)}finally{a&&(a.close(),a=null)}}function M(){L()}function U(){a&&(a.close(),a=null),g("cancelled")}return Y(()=>$.active,c=>{c&&!v.value&&!n.value&&!y.value&&L()}),J(()=>{$.active&&L()}),K(()=>{a&&(a.close(),a=null),f()}),I({retry:M,cancel:U}),(c,s)=>(l(),i("div",de,[y.value?(l(),i("div",he,[t("p",ve,"✅ "+_(B.value),1)])):n.value?(l(),i("div",fe,[t("p",me,_(n.value),1),t("button",{class:"btn-primary",onClick:M,style:{"margin-top":"0.75rem"}},"Try Again")])):A.value==="connecting"?(l(),i("div",ge,[t("div",pe,[t("div",_e,[s[0]||(s[0]=t("p",{class:"pairing-label"},"Enter the code words:",-1)),t("div",we,[(l(!0),i(N,null,j(u.value,(o,R)=>(l(),i("div",{class:"slot-reel",key:R},[t("div",ye,_(o),1)]))),128))]),t("p",ke,_(b.value),1)])]),s[1]||(s[1]=t("div",{class:"waiting-indicator"},[t("div",{class:"spinner-small"}),t("span",null,"Generating code…")],-1))])):(l(),i("div",be,[t("div",$e,[v.value?(l(),i("div",Ae,[s[2]||(s[2]=t("p",{class:"pairing-label"},"Enter the code words:",-1)),t("div",Re,[(l(!0),i(N,null,j(W.value.split(" "),(o,R)=>(l(),i("div",{class:"slot-reel",key:R},[t("div",Se,_(o),1)]))),128))]),t("p",Ce,_(b.value),1)])):P("",!0)]),t("div",Pe,[s[3]||(s[3]=t("div",{class:"spinner-small"},null,-1)),t("span",null,_(E.value),1)])]))]))}},Ee=G(Te,[["__scopeId","data-v-1280e25b"]]),We={class:"app-shell"},Le={key:0,class:"global-status",style:{display:"block"}},Me={class:"view-root"},Ue={key:0,class:"surface surface--tight"},Ie={class:"view-header center"},xe={key:0,class:"user-line"},Be=["innerHTML"],Fe={class:"section-block"},Ve={class:"section-body center"},Oe={key:0,class:"auth-view"},qe=["disabled"],De=["disabled"],Ne=["disabled"],je=["disabled"],He={key:1,class:"auth-view"},ze={__name:"RestrictedAuth",props:{mode:{type:String,default:"login",validator:w=>["login","reauth","forbidden"].includes(w)}},emits:["authenticated","forbidden","logout","back","home","auth-error"],setup(w,{expose:I,emit:x}){const $=w,g=x,v=ee({show:!1,message:"",type:"info"}),y=m(!0),n=m(!1),A=m(null),p=m(null),u=m("initial"),a=m("local"),k=m(null);let W=null;const b=S(()=>!!p.value),E=S(()=>y.value?!1:$.mode==="reauth"?!0:u.value!=="forbidden"),B=S(()=>$.mode==="reauth"?"🔐 Additional Authentication":u.value==="forbidden"?"🚫 Forbidden":`🔐 ${A.value?.rp_name||location.origin}`),C=S(()=>$.mode==="reauth"?"Please verify your identity to continue with this action.":u.value==="forbidden"?"You lack the required permissions.":a.value==="remote"?'Confirm from your other device. Or <a href="#" class="inline-link" data-action="local">this device</a>.':E.value&&$.mode!=="reauth"?'Please sign in with your passkey. Or use <a href="#" class="inline-link" data-action="remote">another device</a>.':"Please sign in with your passkey."),F=S(()=>p.value?.ctx.user.display_name||"User");function f(e,r="info",d=3e3){v.show=!0,v.message=e,v.type=r,W&&clearTimeout(W),d>0&&(W=setTimeout(()=>{v.show=!1},d))}async function L(){try{const e=await Q();if(A.value=e,e?.rp_name){const r=$.mode==="reauth"?"Verify Identity":b.value?"Forbidden":"Sign In";document.title=`${e.rp_name} · ${r}`}}catch(e){console.warn("Unable to load settings",e)}}async function M(){try{p.value=await O("/auth/api/validate",{method:"POST"}),b.value&&$.mode!=="reauth"?(u.value="forbidden",g("forbidden",p.value)):u.value="login"}catch(e){p.value=null,u.value="login",e.status!==401&&e.status!==403&&f(H(e),"error",4e3)}}async function U(){if(!E.value||n.value)return;n.value=!0,f("Starting authentication…","info");let e;try{e=await ne.authenticate()}catch(r){n.value=!1;const d=r?.message||"Passkey authentication cancelled",D=d==="Passkey authentication cancelled";f(d,D?"info":"error",4e3),g("auth-error",{message:d,cancelled:D});return}try{await o(e)}catch(r){n.value=!1;const d=r?.message||"Failed to establish session";f(d,"error",4e3),g("auth-error",{message:d,cancelled:!1});return}n.value=!1,g("authenticated",e)}async function c(){if(!n.value){n.value=!0;try{await O("/auth/api/logout",{method:"POST"}),p.value=null,u.value="login",f("Logged out. You can sign in with a different account.","info",3e3)}catch(e){f(H(e),"error",4e3)}finally{n.value=!1}g("logout")}}function s(){const e=window.open("/auth/","passkey_auth_profile");e&&e.focus()}async function o(e){if(!e?.session_token)throw console.error("setSessionCookie called with missing session_token:",e),new Error("Authentication response missing session_token");return await O("/auth/api/set-session",{method:"POST",headers:{Authorization:`Bearer ${e.session_token}`}})}function R(){a.value="remote"}function T(){a.value="local"}async function h(e){f("Authenticated from another device!","success",2e3);try{await o(e)}catch(r){const d=r?.message||"Failed to establish session";f(d,"error",4e3),g("auth-error",{message:d,cancelled:!1});return}g("authenticated",e)}function V(e){f("Registration approved! Redirecting...","success",2e3);const r=le()||"/auth/";window.location.href=`${r}${e}`}function X(e){}function q(e){const r=e.target;if(r.tagName==="A"&&r.classList.contains("inline-link")){e.preventDefault();const d=r.dataset.action;d==="remote"?R():d==="local"&&T()}}return Y(y,e=>{e||oe(()=>ie(k.value))}),J(async()=>{await L(),await M(),y.value=!1,document.addEventListener("click",q)}),K(()=>{document.removeEventListener("click",q)}),I({showMessage:f,isAuthenticated:b,session:p}),(e,r)=>(l(),i("div",We,[v.show?(l(),i("div",Le,[t("div",{class:te(["status",v.type])},_(v.message),3)])):P("",!0),t("main",Me,[y.value?P("",!0):(l(),i("div",Ue,[t("header",Ie,[t("h1",null,_(B.value),1),b.value?(l(),i("p",xe,"👤 "+_(F.value),1)):P("",!0),t("p",{class:"view-lede",innerHTML:C.value},null,8,Be)]),t("section",Fe,[t("div",Ve,[a.value==="local"?(l(),i("div",Oe,[t("div",{class:"button-row center",ref_key:"buttonRow",ref:k},[se(e.$slots,"actions",{loading:n.value,canAuthenticate:E.value,isAuthenticated:b.value,authenticate:U,logout:c,mode:w.mode},()=>[t("button",{class:"btn-secondary",disabled:n.value,onClick:r[0]||(r[0]=d=>e.$emit("back"))},"Back",8,qe),E.value?(l(),i("button",{key:0,class:"btn-primary",disabled:n.value,onClick:U},_(n.value?w.mode==="reauth"?"Verifying…":"Signing in…":w.mode==="reauth"?"Verify":"Login"),9,De)):P("",!0),b.value&&w.mode!=="reauth"?(l(),i("button",{key:1,class:"btn-danger",disabled:n.value,onClick:c},"Logout",8,Ne)):P("",!0),b.value&&w.mode!=="reauth"?(l(),i("button",{key:2,class:"btn-primary",disabled:n.value,onClick:s},"Profile",8,je)):P("",!0)])],512)])):a.value==="remote"?(l(),i("div",He,[ae(Ee,{active:a.value==="remote",onAuthenticated:h,onRegister:V,onCancelled:T,onError:X},null,8,["active"])])):P("",!0)])])]))])]))}},Je=G(ze,[["__scopeId","data-v-5c04d110"]]);export{Je as R};