@zoreal/oauth2-react 0.1.11 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -33
- package/dist/index.cjs +783 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +72 -18
- package/dist/index.d.ts +72 -18
- package/dist/index.js +775 -106
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -1,29 +1,755 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
// src/context.tsx
|
|
4
|
-
import { createContext, useContext, useMemo } from "react";
|
|
4
|
+
import { createContext, useContext, useMemo, useState as useState2 } from "react";
|
|
5
5
|
|
|
6
6
|
// src/wire.ts
|
|
7
7
|
var WIRE_VERSION = 1;
|
|
8
|
-
var SDK_VERSION = "0.
|
|
8
|
+
var SDK_VERSION = "0.2.6";
|
|
9
9
|
var DEFAULT_ISSUER = "https://id.zoreal.com";
|
|
10
10
|
var POLL_INTERVAL_MS = 2e3;
|
|
11
11
|
var POLL_INTERVAL_ENROLLING_MS = 5e3;
|
|
12
12
|
|
|
13
|
+
// src/PairingModal.tsx
|
|
14
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
15
|
+
import { createPortal } from "react-dom";
|
|
16
|
+
|
|
17
|
+
// src/mark.tsx
|
|
18
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
var ZOREAL_BLUE = "#00b4d9";
|
|
20
|
+
function ZorealMark({
|
|
21
|
+
size = 18,
|
|
22
|
+
brand = false,
|
|
23
|
+
className
|
|
24
|
+
}) {
|
|
25
|
+
return /* @__PURE__ */ jsxs(
|
|
26
|
+
"svg",
|
|
27
|
+
{
|
|
28
|
+
width: size,
|
|
29
|
+
height: size,
|
|
30
|
+
viewBox: "8.4 7.4 62.2 62.2",
|
|
31
|
+
fill: brand ? ZOREAL_BLUE : "currentColor",
|
|
32
|
+
fillRule: "evenodd",
|
|
33
|
+
"aria-hidden": true,
|
|
34
|
+
focusable: "false",
|
|
35
|
+
className,
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx("path", { d: "M56.1,32.9c.6-3.1-.8-6.4-3.7-8.1l-18-10.4,5.2-3,15.4,8.9c5.4,3.1,7.7,9.6,5.8,15.3-.3.8-.6,1.6-1.1,2.4-.4.7-.9,1.4-1.5,2.1-1.3,1.4-2.9,2.6-4.6,3.3-3.6,1.5-7.9,1.4-11.6-.7l-8.9-5.1c-2.9-1.7-6.5-1.3-8.9.8-.6.6-1.2,1.2-1.7,2-.5.8-.8,1.7-.9,2.5-.6,3.1.9,6.4,3.7,8.1l18,10.4-5.2,3-15.4-8.9c-5.4-3.1-7.7-9.6-5.8-15.3.2-.8.6-1.6,1-2.4.5-.7,1-1.4,1.5-2.1,1.3-1.4,2.9-2.6,4.7-3.3,3.6-1.6,7.8-1.4,11.5.6l8.9,5.2c3,1.7,6.6,1.3,8.9-.8.6-.6,1.2-1.2,1.7-2,.4-.8.7-1.7.9-2.5Z" }),
|
|
38
|
+
/* @__PURE__ */ jsx("path", { d: "M68.7,44.2c-.7,1.2-2.3,1.7-3.5.9-1.3-.7-1.7-2.3-1-3.5.7-1.3,2.3-1.7,3.5-1,1.3.7,1.7,2.3,1,3.6Z" }),
|
|
39
|
+
/* @__PURE__ */ jsx("path", { d: "M25.6,21.3c5.1-.8,10.4,0,15.3,2.9l1.2.7h0c1.2.7,1.6,2.3.9,3.5s-2.3,1.7-3.5.9l-1.2-.7c-4.2-2.4-9.1-3-13.5-1.9-1.6.4-3.1,1.1-4.5,1.9h0c-1.2.7-2.8.3-3.5-1-.7-1.2-.3-2.8.9-3.5,0,0,.1,0,.3-.1.3-.1.6-.4,1-.5,2.1-1.1,4.4-1.7,6.7-2.2Z" }),
|
|
40
|
+
/* @__PURE__ */ jsx("path", { d: "M9.6,31.8c.7-1.2,2.4-1.6,3.5-.8,1.2.7,1.6,2.4.8,3.5-.8,1.2-2.4,1.6-3.6.8-1.2-.8-1.5-2.4-.7-3.5Z" }),
|
|
41
|
+
/* @__PURE__ */ jsx("path", { d: "M46.2,30.3c.7-1.3,2.3-1.7,3.5-1,1.2.7,1.7,2.3.9,3.6-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5Z" }),
|
|
42
|
+
/* @__PURE__ */ jsx("path", { d: "M52.1,54.5c-5,.9-10.4,0-15.3-2.8l-1.2-.7h0c-1.2-.7-1.7-2.3-.9-3.5s2.3-1.7,3.5-.9l1.2.7c4.3,2.4,9.1,3,13.6,1.9,1.6-.4,3.1-1.1,4.5-1.9h0c1.2-.7,2.8-.3,3.5.9.7,1.3.3,2.9-.9,3.6-.1,0-.2,0-.3,0-.4.2-.7.4-1.1.6-2.1,1-4.3,1.7-6.7,2.1Z" }),
|
|
43
|
+
/* @__PURE__ */ jsx("path", { d: "M31.4,45.6c-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5,2.3-1.7,3.5-.9,1.7,2.3.9,3.5Z" })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/lockup.tsx
|
|
50
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
51
|
+
function ZorealLockup({ height = 22, className }) {
|
|
52
|
+
return /* @__PURE__ */ jsxs2(
|
|
53
|
+
"svg",
|
|
54
|
+
{
|
|
55
|
+
height,
|
|
56
|
+
width: height * (240 / 58.5),
|
|
57
|
+
viewBox: "0 0 240 58.5",
|
|
58
|
+
role: "img",
|
|
59
|
+
"aria-label": "ZOREAL",
|
|
60
|
+
focusable: "false",
|
|
61
|
+
className,
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ jsx2(
|
|
64
|
+
"path",
|
|
65
|
+
{
|
|
66
|
+
fill: "currentColor",
|
|
67
|
+
d: "M205,40.5h15.3v-3.5h-11.5v-18.4h-3.8v21.8ZM157,22.2v5.6h10.9v3.5h-10.9v5.8h12.5v3.5h-16.3v-21.8h16.2v3.5h-12.4ZM141.4,25.8c0,1.1-.4,2-1.2,2.7-.8.7-1.9,1-3.3,1h-5.6v-7.3h5.6c1.4,0,2.6.3,3.4.9.8.6,1.2,1.5,1.2,2.7ZM146,40.5l-5.9-8.3c.8-.2,1.4-.5,2.1-.9s1.2-.9,1.7-1.4c.4-.5.8-1.2,1.1-1.9s.4-1.5.4-2.4-.1-2-.5-2.9c-.4-.9-.9-1.6-1.7-2.2-.6-.6-1.5-1-2.5-1.4-1-.3-2.2-.4-3.4-.4h-9.8v21.8h3.8v-7.6h4.8l5.4,7.6h4.5ZM115.7,29.7c0,1.1-.1,2.1-.5,3s-.9,1.7-1.5,2.4-1.4,1.2-2.4,1.7c-.9.4-1.9.6-3,.6s-2.1-.1-3-.6-1.7-1-2.4-1.7-1.2-1.5-1.5-2.4-.5-1.9-.5-3,.1-2.1.5-3,.9-1.7,1.5-2.4,1.4-1.2,2.4-1.7c.9-.4,1.9-.6,3-.6s2.1.2,3,.6c.9.4,1.7,1,2.3,1.7.6.6,1.2,1.5,1.6,2.4s.5,1.9.5,3ZM119.7,29.6c0-1.5-.3-3-.8-4.4-.6-1.4-1.4-2.5-2.4-3.6-1-1-2.2-1.8-3.6-2.4-1.4-.6-3-.9-4.6-.9s-3.2.4-4.6.9c-1.4.6-2.7,1.4-3.7,2.4s-1.8,2.2-2.4,3.6c-.5,1.4-.8,2.8-.8,4.4s.3,3,.8,4.4c.6,1.4,1.4,2.5,2.4,3.6,1,1,2.2,1.8,3.6,2.4,1.4.6,3,.9,4.6.9s3.2-.4,4.6-.9c1.4-.6,2.6-1.4,3.7-2.4,1-1,1.8-2.2,2.4-3.6.5-1.4.8-2.9.8-4.4ZM86.1,22.1l-13,15.6v2.8h17.9v-3.4h-12.9l12.9-15.6v-2.8h-17.5v3.4h12.5ZM188.5,18.5h-3.5l-9.6,22h4c3.7-8.8,3.4-8,7.4-17.4,3.7,8.8,3.9,9.1,7.4,17.4h4l-9.6-22Z"
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
/* @__PURE__ */ jsxs2("g", { fill: ZOREAL_BLUE, fillRule: "evenodd", children: [
|
|
71
|
+
/* @__PURE__ */ jsx2("path", { d: "M52,25.7c.4-2-.5-4.2-2.5-5.4l-11.8-6.8,3.4-2,10.1,5.9c3.6,2,5.1,6.3,3.8,10.1-.2.5-.4,1-.7,1.6-.3.5-.6.9-1,1.4-.9.9-1.9,1.7-3,2.2-2.4,1-5.2.9-7.6-.5l-5.9-3.4c-1.9-1.1-4.3-.9-5.9.5-.4.4-.8.8-1.1,1.3-.3.5-.5,1.1-.6,1.7-.4,2,.6,4.2,2.5,5.4l11.8,6.8-3.4,2-10.1-5.9c-3.6-2-5.1-6.3-3.8-10.1.1-.5.4-1,.7-1.6.3-.5.7-.9,1-1.4.9-.9,1.9-1.7,3.1-2.2,2.4-1,5.2-.9,7.6.4l5.9,3.4c1.9,1.1,4.3.9,5.9-.5.4-.4.8-.8,1.1-1.3.3-.5.5-1.1.6-1.7Z" }),
|
|
72
|
+
/* @__PURE__ */ jsx2("path", { d: "M60.3,33.1c-.5.8-1.5,1.1-2.3.6-.9-.5-1.1-1.5-.7-2.3.5-.9,1.5-1.1,2.3-.7.9.5,1.1,1.5.7,2.4Z" }),
|
|
73
|
+
/* @__PURE__ */ jsx2("path", { d: "M31.9,18c3.4-.5,6.9,0,10,1.9l.8.5h0c.8.5,1,1.5.6,2.3s-1.5,1.1-2.3.6l-.8-.5c-2.8-1.6-6-1.9-8.9-1.2-1,.3-2,.7-3,1.2h0c-.8.5-1.8.2-2.3-.7-.5-.8-.2-1.8.6-2.3,0,0,0,0,.2,0,.2,0,.4-.2.7-.3,1.4-.7,2.9-1.1,4.4-1.4Z" }),
|
|
74
|
+
/* @__PURE__ */ jsx2("path", { d: "M21.4,24.9c.5-.8,1.6-1,2.3-.5.8.5,1,1.6.5,2.3-.5.8-1.6,1-2.4.5-.8-.5-1-1.6-.5-2.3Z" }),
|
|
75
|
+
/* @__PURE__ */ jsx2("path", { d: "M45.5,23.9c.5-.9,1.5-1.1,2.3-.7.8.5,1.1,1.5.6,2.4-.5.8-1.5,1.1-2.3.6s-1.1-1.5-.6-2.3Z" }),
|
|
76
|
+
/* @__PURE__ */ jsx2("path", { d: "M49.4,39.9c-3.3.6-6.9,0-10-1.8l-.8-.5h0c-.8-.5-1.1-1.5-.6-2.3s1.5-1.1,2.3-.6l.8.5c2.8,1.6,6,1.9,9,1.2,1-.3,2-.7,3-1.2h0c.8-.5,1.8-.2,2.3.6.5.9.2,1.9-.6,2.4,0,0-.1,0-.2,0-.2.1-.5.3-.7.4-1.4.7-2.8,1.1-4.4,1.4Z" }),
|
|
77
|
+
/* @__PURE__ */ jsx2("path", { d: "M35.8,34c-.5.8-1.5,1.1-2.3.6s-1.1-1.5-.6-2.3,1.5-1.1,2.3-.6,1.1,1.5.6,2.3Z" })
|
|
78
|
+
] })
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/i18n.ts
|
|
85
|
+
var en = {
|
|
86
|
+
title: "Scan to sign in",
|
|
87
|
+
titleApprove: "Approve on your phone",
|
|
88
|
+
bodyScan: "Scan with your phone camera or the ZOREAL ID app.",
|
|
89
|
+
bodyApprove: "Approve the login in your ZOREAL ID app.",
|
|
90
|
+
bodyEnrolling: "Finish setting up ZOREAL ID on your phone, then approve the login.",
|
|
91
|
+
waiting: "Waiting for scan",
|
|
92
|
+
waitingApproval: "Waiting for approval",
|
|
93
|
+
expiresIn: "Expires in {time}",
|
|
94
|
+
secured: "Proof-of-Human verification by ZOREAL",
|
|
95
|
+
noIdTitle: "No ZOREAL ID yet?",
|
|
96
|
+
noIdBody: "Scan the same code to download the app and create one for free. It only takes a minute.",
|
|
97
|
+
cancel: "Cancel",
|
|
98
|
+
close: "Close",
|
|
99
|
+
qrAlt: "QR code to sign in with ZOREAL"
|
|
100
|
+
};
|
|
101
|
+
var TRANSLATIONS = {
|
|
102
|
+
en,
|
|
103
|
+
sv: {
|
|
104
|
+
title: "Skanna f\xF6r att logga in",
|
|
105
|
+
titleApprove: "Godk\xE4nn p\xE5 telefonen",
|
|
106
|
+
bodyScan: "Skanna med telefonens kamera eller ZOREAL ID-appen.",
|
|
107
|
+
bodyApprove: "Godk\xE4nn inloggningen i ZOREAL ID-appen.",
|
|
108
|
+
bodyEnrolling: "Slutf\xF6r konfigurationen av ZOREAL ID p\xE5 telefonen och godk\xE4nn sedan inloggningen.",
|
|
109
|
+
waiting: "V\xE4ntar p\xE5 skanning",
|
|
110
|
+
waitingApproval: "V\xE4ntar p\xE5 godk\xE4nnande",
|
|
111
|
+
expiresIn: "Upph\xF6r om {time}",
|
|
112
|
+
secured: "Proof-of-Human-verifiering av ZOREAL",
|
|
113
|
+
noIdTitle: "Har du inget ZOREAL ID?",
|
|
114
|
+
noIdBody: "Skanna samma kod f\xF6r att ladda ner appen och skapa ett gratis. Det tar bara en minut.",
|
|
115
|
+
cancel: "Avbryt",
|
|
116
|
+
close: "St\xE4ng",
|
|
117
|
+
qrAlt: "QR-kod f\xF6r att logga in med ZOREAL"
|
|
118
|
+
},
|
|
119
|
+
es: {
|
|
120
|
+
title: "Escanea para iniciar sesi\xF3n",
|
|
121
|
+
titleApprove: "Apru\xE9balo en tu tel\xE9fono",
|
|
122
|
+
bodyScan: "Escanea con la c\xE1mara de tu tel\xE9fono o con la app ZOREAL ID.",
|
|
123
|
+
bodyApprove: "Aprueba el inicio de sesi\xF3n en tu app ZOREAL ID.",
|
|
124
|
+
bodyEnrolling: "Termina de configurar ZOREAL ID en tu tel\xE9fono y luego aprueba el inicio de sesi\xF3n.",
|
|
125
|
+
waiting: "Esperando el escaneo",
|
|
126
|
+
waitingApproval: "Esperando aprobaci\xF3n",
|
|
127
|
+
expiresIn: "Caduca en {time}",
|
|
128
|
+
secured: "Verificaci\xF3n Proof-of-Human de ZOREAL",
|
|
129
|
+
noIdTitle: "\xBFA\xFAn no tienes ZOREAL ID?",
|
|
130
|
+
noIdBody: "Escanea el mismo c\xF3digo para descargar la app y crear una gratis. Solo toma un minuto.",
|
|
131
|
+
cancel: "Cancelar",
|
|
132
|
+
close: "Cerrar",
|
|
133
|
+
qrAlt: "C\xF3digo QR para iniciar sesi\xF3n con ZOREAL"
|
|
134
|
+
},
|
|
135
|
+
pt: {
|
|
136
|
+
title: "Digitalize para entrar",
|
|
137
|
+
titleApprove: "Aprove no seu telefone",
|
|
138
|
+
bodyScan: "Digitalize com a c\xE2mera do seu telefone ou com o app ZOREAL ID.",
|
|
139
|
+
bodyApprove: "Aprove o login no app ZOREAL ID.",
|
|
140
|
+
bodyEnrolling: "Termine de configurar o ZOREAL ID no seu telefone e depois aprove o login.",
|
|
141
|
+
waiting: "Aguardando digitaliza\xE7\xE3o",
|
|
142
|
+
waitingApproval: "Aguardando aprova\xE7\xE3o",
|
|
143
|
+
expiresIn: "Expira em {time}",
|
|
144
|
+
secured: "Verifica\xE7\xE3o Proof-of-Human da ZOREAL",
|
|
145
|
+
noIdTitle: "Ainda n\xE3o tem ZOREAL ID?",
|
|
146
|
+
noIdBody: "Digitalize o mesmo c\xF3digo para baixar o app e criar uma conta gr\xE1tis. Leva s\xF3 um minuto.",
|
|
147
|
+
cancel: "Cancelar",
|
|
148
|
+
close: "Fechar",
|
|
149
|
+
qrAlt: "C\xF3digo QR para entrar com ZOREAL"
|
|
150
|
+
},
|
|
151
|
+
fr: {
|
|
152
|
+
title: "Scannez pour vous connecter",
|
|
153
|
+
titleApprove: "Approuvez sur votre t\xE9l\xE9phone",
|
|
154
|
+
bodyScan: "Scannez avec l'appareil photo de votre t\xE9l\xE9phone ou l'app ZOREAL ID.",
|
|
155
|
+
bodyApprove: "Approuvez la connexion dans votre app ZOREAL ID.",
|
|
156
|
+
bodyEnrolling: "Terminez la configuration de ZOREAL ID sur votre t\xE9l\xE9phone, puis approuvez la connexion.",
|
|
157
|
+
waiting: "En attente du scan",
|
|
158
|
+
waitingApproval: "En attente d'approbation",
|
|
159
|
+
expiresIn: "Expire dans {time}",
|
|
160
|
+
secured: "V\xE9rification Proof-of-Human par ZOREAL",
|
|
161
|
+
noIdTitle: "Pas encore de ZOREAL ID ?",
|
|
162
|
+
noIdBody: "Scannez le m\xEAme code pour t\xE9l\xE9charger l'app et en cr\xE9er un gratuitement. Cela prend une minute.",
|
|
163
|
+
cancel: "Annuler",
|
|
164
|
+
close: "Fermer",
|
|
165
|
+
qrAlt: "Code QR pour se connecter avec ZOREAL"
|
|
166
|
+
},
|
|
167
|
+
de: {
|
|
168
|
+
title: "Zum Anmelden scannen",
|
|
169
|
+
titleApprove: "Auf dem Handy best\xE4tigen",
|
|
170
|
+
bodyScan: "Mit der Handykamera oder der ZOREAL ID App scannen.",
|
|
171
|
+
bodyApprove: "Anmeldung in der ZOREAL ID App best\xE4tigen.",
|
|
172
|
+
bodyEnrolling: "ZOREAL ID auf dem Handy fertig einrichten und dann die Anmeldung best\xE4tigen.",
|
|
173
|
+
waiting: "Warten auf Scan",
|
|
174
|
+
waitingApproval: "Warten auf Best\xE4tigung",
|
|
175
|
+
expiresIn: "L\xE4uft ab in {time}",
|
|
176
|
+
secured: "Proof-of-Human-Verifizierung von ZOREAL",
|
|
177
|
+
noIdTitle: "Noch keine ZOREAL ID?",
|
|
178
|
+
noIdBody: "Denselben Code scannen, um die App zu laden und kostenlos eine zu erstellen. Dauert nur eine Minute.",
|
|
179
|
+
cancel: "Abbrechen",
|
|
180
|
+
close: "Schlie\xDFen",
|
|
181
|
+
qrAlt: "QR-Code f\xFCr die Anmeldung mit ZOREAL"
|
|
182
|
+
},
|
|
183
|
+
ru: {
|
|
184
|
+
title: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435, \u0447\u0442\u043E\u0431\u044B \u0432\u043E\u0439\u0442\u0438",
|
|
185
|
+
titleApprove: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0435",
|
|
186
|
+
bodyScan: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435 \u043A\u0430\u043C\u0435\u0440\u043E\u0439 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430 \u0438\u043B\u0438 \u0447\u0435\u0440\u0435\u0437 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 ZOREAL ID.",
|
|
187
|
+
bodyApprove: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0432\u0445\u043E\u0434 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438 ZOREAL ID.",
|
|
188
|
+
bodyEnrolling: "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0443 ZOREAL ID \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0435, \u0437\u0430\u0442\u0435\u043C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0432\u0445\u043E\u0434.",
|
|
189
|
+
waiting: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u0441\u043A\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F",
|
|
190
|
+
waitingApproval: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F",
|
|
191
|
+
expiresIn: "\u0418\u0441\u0442\u0435\u043A\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 {time}",
|
|
192
|
+
secured: "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 Proof-of-Human \u043E\u0442 ZOREAL",
|
|
193
|
+
noIdTitle: "\u0415\u0449\u0451 \u043D\u0435\u0442 ZOREAL ID?",
|
|
194
|
+
noIdBody: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435 \u0442\u043E\u0442 \u0436\u0435 \u043A\u043E\u0434, \u0447\u0442\u043E\u0431\u044B \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0438 \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0435\u0433\u043E \u0431\u0435\u0441\u043F\u043B\u0430\u0442\u043D\u043E. \u042D\u0442\u043E \u0437\u0430\u0439\u043C\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0443.",
|
|
195
|
+
cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
|
|
196
|
+
close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
|
|
197
|
+
qrAlt: "QR-\u043A\u043E\u0434 \u0434\u043B\u044F \u0432\u0445\u043E\u0434\u0430 \u0447\u0435\u0440\u0435\u0437 ZOREAL"
|
|
198
|
+
},
|
|
199
|
+
ja: {
|
|
200
|
+
title: "\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30ED\u30B0\u30A4\u30F3",
|
|
201
|
+
titleApprove: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3067\u627F\u8A8D",
|
|
202
|
+
bodyScan: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u306E\u30AB\u30E1\u30E9\u307E\u305F\u306FZOREAL ID\u30A2\u30D7\u30EA\u3067\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
203
|
+
bodyApprove: "ZOREAL ID\u30A2\u30D7\u30EA\u3067\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
204
|
+
bodyEnrolling: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3067ZOREAL ID\u306E\u8A2D\u5B9A\u3092\u5B8C\u4E86\u3057\u3001\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
205
|
+
waiting: "\u30B9\u30AD\u30E3\u30F3\u5F85\u3061",
|
|
206
|
+
waitingApproval: "\u627F\u8A8D\u5F85\u3061",
|
|
207
|
+
expiresIn: "\u6709\u52B9\u671F\u9650\u307E\u3067 {time}",
|
|
208
|
+
secured: "ZOREAL\u306B\u3088\u308BProof-of-Human\u8A8D\u8A3C",
|
|
209
|
+
noIdTitle: "ZOREAL ID\u3092\u304A\u6301\u3061\u3067\u306A\u3044\u3067\u3059\u304B\uFF1F",
|
|
210
|
+
noIdBody: "\u540C\u3058\u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30A2\u30D7\u30EA\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3057\u3001\u7121\u6599\u3067\u4F5C\u6210\u3067\u304D\u307E\u3059\u30021\u5206\u307B\u3069\u3067\u5B8C\u4E86\u3057\u307E\u3059\u3002",
|
|
211
|
+
cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
|
|
212
|
+
close: "\u9589\u3058\u308B",
|
|
213
|
+
qrAlt: "ZOREAL\u3067\u30ED\u30B0\u30A4\u30F3\u3059\u308B\u305F\u3081\u306EQR\u30B3\u30FC\u30C9"
|
|
214
|
+
},
|
|
215
|
+
hi: {
|
|
216
|
+
title: "\u0938\u093E\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902",
|
|
217
|
+
titleApprove: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u092A\u0930 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902",
|
|
218
|
+
bodyScan: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u0915\u0947 \u0915\u0948\u092E\u0930\u0947 \u092F\u093E ZOREAL ID \u0910\u092A \u0938\u0947 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902\u0964",
|
|
219
|
+
bodyApprove: "\u0905\u092A\u0928\u0947 ZOREAL ID \u0910\u092A \u092E\u0947\u0902 \u0932\u0949\u0917\u093F\u0928 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902\u0964",
|
|
220
|
+
bodyEnrolling: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u092A\u0930 ZOREAL ID \u0938\u0947\u091F\u0905\u092A \u092A\u0942\u0930\u093E \u0915\u0930\u0947\u0902, \u092B\u093F\u0930 \u0932\u0949\u0917\u093F\u0928 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902\u0964",
|
|
221
|
+
waiting: "\u0938\u094D\u0915\u0948\u0928 \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
|
|
222
|
+
waitingApproval: "\u0938\u094D\u0935\u0940\u0915\u0943\u0924\u093F \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
|
|
223
|
+
expiresIn: "{time} \u092E\u0947\u0902 \u0938\u092E\u093E\u092A\u094D\u0924",
|
|
224
|
+
secured: "ZOREAL \u0926\u094D\u0935\u093E\u0930\u093E Proof-of-Human \u0938\u0924\u094D\u092F\u093E\u092A\u0928",
|
|
225
|
+
noIdTitle: "\u0905\u092D\u0940 \u0924\u0915 ZOREAL ID \u0928\u0939\u0940\u0902 \u0939\u0948?",
|
|
226
|
+
noIdBody: "\u0910\u092A \u0921\u093E\u0909\u0928\u0932\u094B\u0921 \u0915\u0930\u0928\u0947 \u0914\u0930 \u092E\u0941\u092B\u094D\u0924 \u092E\u0947\u0902 \u090F\u0915 \u092C\u0928\u093E\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0935\u0939\u0940 \u0915\u094B\u0921 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902\u0964 \u0907\u0938\u092E\u0947\u0902 \u092C\u0938 \u090F\u0915 \u092E\u093F\u0928\u091F \u0932\u0917\u0924\u093E \u0939\u0948\u0964",
|
|
227
|
+
cancel: "\u0930\u0926\u094D\u0926 \u0915\u0930\u0947\u0902",
|
|
228
|
+
close: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
|
|
229
|
+
qrAlt: "ZOREAL \u0938\u0947 \u0938\u093E\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F QR \u0915\u094B\u0921"
|
|
230
|
+
},
|
|
231
|
+
zhs: {
|
|
232
|
+
title: "\u626B\u7801\u767B\u5F55",
|
|
233
|
+
titleApprove: "\u5728\u624B\u673A\u4E0A\u6279\u51C6",
|
|
234
|
+
bodyScan: "\u4F7F\u7528\u624B\u673A\u76F8\u673A\u6216 ZOREAL ID \u5E94\u7528\u626B\u63CF\u3002",
|
|
235
|
+
bodyApprove: "\u8BF7\u5728 ZOREAL ID \u5E94\u7528\u4E2D\u6279\u51C6\u767B\u5F55\u3002",
|
|
236
|
+
bodyEnrolling: "\u8BF7\u5728\u624B\u673A\u4E0A\u5B8C\u6210 ZOREAL ID \u8BBE\u7F6E\uFF0C\u7136\u540E\u6279\u51C6\u767B\u5F55\u3002",
|
|
237
|
+
waiting: "\u7B49\u5F85\u626B\u63CF",
|
|
238
|
+
waitingApproval: "\u7B49\u5F85\u6279\u51C6",
|
|
239
|
+
expiresIn: "{time} \u540E\u5931\u6548",
|
|
240
|
+
secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A8C\u8BC1",
|
|
241
|
+
noIdTitle: "\u8FD8\u6CA1\u6709 ZOREAL ID\uFF1F",
|
|
242
|
+
noIdBody: "\u626B\u63CF\u540C\u4E00\u4E2A\u4E8C\u7EF4\u7801\u5373\u53EF\u4E0B\u8F7D\u5E94\u7528\u5E76\u514D\u8D39\u521B\u5EFA\uFF0C\u53EA\u9700\u4E00\u5206\u949F\u3002",
|
|
243
|
+
cancel: "\u53D6\u6D88",
|
|
244
|
+
close: "\u5173\u95ED",
|
|
245
|
+
qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5F55\u7684\u4E8C\u7EF4\u7801"
|
|
246
|
+
},
|
|
247
|
+
zht: {
|
|
248
|
+
title: "\u6383\u78BC\u767B\u5165",
|
|
249
|
+
titleApprove: "\u5728\u624B\u6A5F\u4E0A\u6838\u51C6",
|
|
250
|
+
bodyScan: "\u4F7F\u7528\u624B\u6A5F\u76F8\u6A5F\u6216 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u6383\u63CF\u3002",
|
|
251
|
+
bodyApprove: "\u8ACB\u5728 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u4E2D\u6838\u51C6\u767B\u5165\u3002",
|
|
252
|
+
bodyEnrolling: "\u8ACB\u5728\u624B\u6A5F\u4E0A\u5B8C\u6210 ZOREAL ID \u8A2D\u5B9A\uFF0C\u7136\u5F8C\u6838\u51C6\u767B\u5165\u3002",
|
|
253
|
+
waiting: "\u7B49\u5F85\u6383\u63CF",
|
|
254
|
+
waitingApproval: "\u7B49\u5F85\u6838\u51C6",
|
|
255
|
+
expiresIn: "{time} \u5F8C\u5931\u6548",
|
|
256
|
+
secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A57\u8B49",
|
|
257
|
+
noIdTitle: "\u9084\u6C92\u6709 ZOREAL ID\uFF1F",
|
|
258
|
+
noIdBody: "\u6383\u63CF\u540C\u4E00\u500B QR code \u5373\u53EF\u4E0B\u8F09\u61C9\u7528\u7A0B\u5F0F\u4E26\u514D\u8CBB\u5EFA\u7ACB\uFF0C\u53EA\u9700\u4E00\u5206\u9418\u3002",
|
|
259
|
+
cancel: "\u53D6\u6D88",
|
|
260
|
+
close: "\u95DC\u9589",
|
|
261
|
+
qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5165\u7684 QR code"
|
|
262
|
+
},
|
|
263
|
+
ar: {
|
|
264
|
+
title: "\u0627\u0645\u0633\u062D \u0644\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644",
|
|
265
|
+
titleApprove: "\u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u0647\u0627\u062A\u0641\u0643",
|
|
266
|
+
bodyScan: "\u0627\u0645\u0633\u062D \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0643\u0627\u0645\u064A\u0631\u0627 \u0647\u0627\u062A\u0641\u0643 \u0623\u0648 \u062A\u0637\u0628\u064A\u0642 ZOREAL ID.",
|
|
267
|
+
bodyApprove: "\u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0641\u064A \u062A\u0637\u0628\u064A\u0642 ZOREAL ID.",
|
|
268
|
+
bodyEnrolling: "\u0623\u0643\u0645\u0644 \u0625\u0639\u062F\u0627\u062F ZOREAL ID \u0639\u0644\u0649 \u0647\u0627\u062A\u0641\u0643\u060C \u062B\u0645 \u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644.",
|
|
269
|
+
waiting: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0633\u062D",
|
|
270
|
+
waitingApproval: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0648\u0627\u0641\u0642\u0629",
|
|
271
|
+
expiresIn: "\u062A\u0646\u062A\u0647\u064A \u0627\u0644\u0635\u0644\u0627\u062D\u064A\u0629 \u062E\u0644\u0627\u0644 {time}",
|
|
272
|
+
secured: "\u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 Proof-of-Human \u0628\u0648\u0627\u0633\u0637\u0629 ZOREAL",
|
|
273
|
+
noIdTitle: "\u0644\u064A\u0633 \u0644\u062F\u064A\u0643 ZOREAL ID \u0628\u0639\u062F\u061F",
|
|
274
|
+
noIdBody: "\u0627\u0645\u0633\u062D \u0627\u0644\u0631\u0645\u0632 \u0646\u0641\u0633\u0647 \u0644\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u062A\u0637\u0628\u064A\u0642 \u0648\u0625\u0646\u0634\u0627\u0621 \u062D\u0633\u0627\u0628 \u0645\u062C\u0627\u0646\u064A. \u064A\u0633\u062A\u063A\u0631\u0642 \u0627\u0644\u0623\u0645\u0631 \u062F\u0642\u064A\u0642\u0629 \u0648\u0627\u062D\u062F\u0629 \u0641\u0642\u0637.",
|
|
275
|
+
cancel: "\u0625\u0644\u063A\u0627\u0621",
|
|
276
|
+
close: "\u0625\u063A\u0644\u0627\u0642",
|
|
277
|
+
qrAlt: "\u0631\u0645\u0632 QR \u0644\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 ZOREAL"
|
|
278
|
+
},
|
|
279
|
+
ko: {
|
|
280
|
+
title: "\uC2A4\uCE94\uD558\uC5EC \uB85C\uADF8\uC778",
|
|
281
|
+
titleApprove: "\uD734\uB300\uD3F0\uC5D0\uC11C \uC2B9\uC778",
|
|
282
|
+
bodyScan: "\uD734\uB300\uD3F0 \uCE74\uBA54\uB77C \uB610\uB294 ZOREAL ID \uC571\uC73C\uB85C \uC2A4\uCE94\uD558\uC138\uC694.",
|
|
283
|
+
bodyApprove: "ZOREAL ID \uC571\uC5D0\uC11C \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
|
|
284
|
+
bodyEnrolling: "\uD734\uB300\uD3F0\uC5D0\uC11C ZOREAL ID \uC124\uC815\uC744 \uC644\uB8CC\uD55C \uD6C4 \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
|
|
285
|
+
waiting: "\uC2A4\uCE94 \uB300\uAE30 \uC911",
|
|
286
|
+
waitingApproval: "\uC2B9\uC778 \uB300\uAE30 \uC911",
|
|
287
|
+
expiresIn: "{time} \uD6C4 \uB9CC\uB8CC",
|
|
288
|
+
secured: "ZOREAL\uC758 Proof-of-Human \uC778\uC99D",
|
|
289
|
+
noIdTitle: "\uC544\uC9C1 ZOREAL ID\uAC00 \uC5C6\uC73C\uC2E0\uAC00\uC694?",
|
|
290
|
+
noIdBody: "\uAC19\uC740 \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD574 \uC571\uC744 \uB0B4\uB824\uBC1B\uACE0 \uBB34\uB8CC\uB85C \uB9CC\uB4DC\uC138\uC694. 1\uBD84\uC774\uBA74 \uB429\uB2C8\uB2E4.",
|
|
291
|
+
cancel: "\uCDE8\uC18C",
|
|
292
|
+
close: "\uB2EB\uAE30",
|
|
293
|
+
qrAlt: "ZOREAL\uB85C \uB85C\uADF8\uC778\uD558\uAE30 \uC704\uD55C QR \uCF54\uB4DC"
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
var RTL = /* @__PURE__ */ new Set(["ar", "he", "fa", "ur"]);
|
|
297
|
+
function lookup(locale) {
|
|
298
|
+
const tag = locale.toLowerCase().replace(/_/g, "-");
|
|
299
|
+
const primary = tag.split("-")[0];
|
|
300
|
+
if (primary === "zh") {
|
|
301
|
+
const simplified = /(^|-)(hans|cn|sg|my)(-|$)/.test(tag);
|
|
302
|
+
return TRANSLATIONS[simplified ? "zhs" : "zht"];
|
|
303
|
+
}
|
|
304
|
+
return TRANSLATIONS[tag] ?? TRANSLATIONS[primary];
|
|
305
|
+
}
|
|
306
|
+
function browserLocales() {
|
|
307
|
+
if (typeof navigator === "undefined") return [];
|
|
308
|
+
const nav = navigator;
|
|
309
|
+
if (nav.languages && nav.languages.length) return [...nav.languages];
|
|
310
|
+
return nav.language ? [nav.language] : [];
|
|
311
|
+
}
|
|
312
|
+
function strings(locale) {
|
|
313
|
+
if (locale) return lookup(locale) ?? en;
|
|
314
|
+
for (const candidate of browserLocales()) {
|
|
315
|
+
const hit = lookup(candidate);
|
|
316
|
+
if (hit) return hit;
|
|
317
|
+
}
|
|
318
|
+
return en;
|
|
319
|
+
}
|
|
320
|
+
function isRtl(locale) {
|
|
321
|
+
const tag = locale ?? browserLocales()[0];
|
|
322
|
+
if (!tag) return false;
|
|
323
|
+
return RTL.has(tag.toLowerCase().replace(/_/g, "-").split("-")[0]);
|
|
324
|
+
}
|
|
325
|
+
function interpolate(template, time) {
|
|
326
|
+
return template.replace("{time}", time);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// src/styles.ts
|
|
330
|
+
var PREFIX = "zrl";
|
|
331
|
+
var cx = (name) => `${PREFIX}-${name}`;
|
|
332
|
+
var STYLE_ELEMENT_ID = "zoreal-pairing-styles";
|
|
333
|
+
var LIGHT = `
|
|
334
|
+
--zrl-scrim: rgba(16, 18, 27, 0.45);
|
|
335
|
+
--zrl-surface: #ffffff;
|
|
336
|
+
--zrl-surface-sunken: #f6f7f9;
|
|
337
|
+
--zrl-ink: #16181c;
|
|
338
|
+
--zrl-ink-soft: #4a4f57;
|
|
339
|
+
--zrl-ink-mute: #6b7078;
|
|
340
|
+
--zrl-line: #e4e6ea;
|
|
341
|
+
--zrl-line-soft: #eef0f3;
|
|
342
|
+
--zrl-accent: #00b4d9;
|
|
343
|
+
--zrl-accent-soft: #dcf3fa;
|
|
344
|
+
--zrl-accent-ink: #04698a;
|
|
345
|
+
--zrl-urgent: #b4761a;
|
|
346
|
+
--zrl-qr-bg: #ffffff;
|
|
347
|
+
--zrl-shadow: 0 1px 2px rgba(16, 18, 27, 0.06), 0 20px 50px -12px rgba(16, 18, 27, 0.3);
|
|
348
|
+
--zrl-ring: rgba(16, 18, 27, 0.07);
|
|
349
|
+
`;
|
|
350
|
+
var DARK = `
|
|
351
|
+
--zrl-scrim: rgba(0, 0, 0, 0.62);
|
|
352
|
+
--zrl-surface: #17191d;
|
|
353
|
+
--zrl-surface-sunken: #1f2226;
|
|
354
|
+
--zrl-ink: #f4f5f7;
|
|
355
|
+
--zrl-ink-soft: #b3b8c0;
|
|
356
|
+
--zrl-ink-mute: #8b9199;
|
|
357
|
+
--zrl-line: #2c3036;
|
|
358
|
+
--zrl-line-soft: #24272c;
|
|
359
|
+
--zrl-accent: #34c9e8;
|
|
360
|
+
--zrl-accent-soft: #0d3b47;
|
|
361
|
+
--zrl-accent-ink: #7fdcf0;
|
|
362
|
+
--zrl-urgent: #e0a952;
|
|
363
|
+
/* The QR well stays white in dark mode on purpose: a scanner needs the
|
|
364
|
+
quiet-zone contrast, and an inverted QR fails on a good number of phone
|
|
365
|
+
cameras. It reads as a deliberate light panel, not a theming miss. */
|
|
366
|
+
--zrl-qr-bg: #ffffff;
|
|
367
|
+
--zrl-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 20px 50px -12px rgba(0, 0, 0, 0.65);
|
|
368
|
+
--zrl-ring: rgba(255, 255, 255, 0.1);
|
|
369
|
+
`;
|
|
370
|
+
var CSS = `
|
|
371
|
+
.${PREFIX}-root { ${LIGHT} }
|
|
372
|
+
.${PREFIX}-root[data-theme="dark"] { ${DARK} }
|
|
373
|
+
@media (prefers-color-scheme: dark) {
|
|
374
|
+
.${PREFIX}-root[data-theme="auto"] { ${DARK} }
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.${PREFIX}-scrim {
|
|
378
|
+
position: fixed;
|
|
379
|
+
inset: 0;
|
|
380
|
+
z-index: 2147483000;
|
|
381
|
+
display: grid;
|
|
382
|
+
place-items: center;
|
|
383
|
+
overflow-y: auto;
|
|
384
|
+
padding: 16px;
|
|
385
|
+
background: var(--zrl-scrim);
|
|
386
|
+
backdrop-filter: blur(3px);
|
|
387
|
+
-webkit-backdrop-filter: blur(3px);
|
|
388
|
+
font-family: inherit;
|
|
389
|
+
animation: ${PREFIX}-fade 200ms ease-out both;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.${PREFIX}-card {
|
|
393
|
+
position: relative;
|
|
394
|
+
box-sizing: border-box;
|
|
395
|
+
width: 100%;
|
|
396
|
+
max-width: 380px;
|
|
397
|
+
border-radius: 16px;
|
|
398
|
+
background: var(--zrl-surface);
|
|
399
|
+
color: var(--zrl-ink);
|
|
400
|
+
box-shadow: var(--zrl-shadow);
|
|
401
|
+
outline: 1px solid var(--zrl-ring);
|
|
402
|
+
outline-offset: -1px;
|
|
403
|
+
text-align: center;
|
|
404
|
+
animation: ${PREFIX}-rise 300ms cubic-bezier(0.23, 1, 0.32, 1) both;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.${PREFIX}-body { padding: 28px 24px 20px; }
|
|
408
|
+
|
|
409
|
+
.${PREFIX}-lockup { display: block; margin: 0 auto; color: var(--zrl-ink); }
|
|
410
|
+
|
|
411
|
+
.${PREFIX}-title {
|
|
412
|
+
margin: 18px 0 0;
|
|
413
|
+
font-size: 18px;
|
|
414
|
+
font-weight: 600;
|
|
415
|
+
letter-spacing: -0.01em;
|
|
416
|
+
line-height: 1.3;
|
|
417
|
+
color: var(--zrl-ink);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.${PREFIX}-body-text {
|
|
421
|
+
margin: 6px auto 0;
|
|
422
|
+
max-width: 30ch;
|
|
423
|
+
font-size: 14px;
|
|
424
|
+
line-height: 1.55;
|
|
425
|
+
color: var(--zrl-ink-soft);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.${PREFIX}-qr-well {
|
|
429
|
+
position: relative;
|
|
430
|
+
display: grid;
|
|
431
|
+
place-items: center;
|
|
432
|
+
box-sizing: border-box;
|
|
433
|
+
width: 204px;
|
|
434
|
+
height: 204px;
|
|
435
|
+
margin: 20px auto 0;
|
|
436
|
+
padding: 12px;
|
|
437
|
+
border: 1px solid var(--zrl-line);
|
|
438
|
+
border-radius: 16px;
|
|
439
|
+
background: var(--zrl-qr-bg);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.${PREFIX}-qr {
|
|
443
|
+
display: block;
|
|
444
|
+
width: 100%;
|
|
445
|
+
height: 100%;
|
|
446
|
+
border-radius: 8px;
|
|
447
|
+
transition: filter 300ms cubic-bezier(0.23, 1, 0.32, 1),
|
|
448
|
+
opacity 300ms cubic-bezier(0.23, 1, 0.32, 1),
|
|
449
|
+
transform 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/* Once the code is claimed the QR is spent. Blurring it out rather than
|
|
453
|
+
swapping it keeps one object on screen through the state change, so the eye
|
|
454
|
+
reads a transformation instead of two things trading places. */
|
|
455
|
+
.${PREFIX}-qr[data-spent="true"] { opacity: 0.2; filter: blur(3px); transform: scale(0.96); }
|
|
456
|
+
|
|
457
|
+
.${PREFIX}-qr-overlay {
|
|
458
|
+
position: absolute;
|
|
459
|
+
inset: 0;
|
|
460
|
+
display: grid;
|
|
461
|
+
place-items: center;
|
|
462
|
+
animation: ${PREFIX}-fade 200ms ease-out both;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.${PREFIX}-qr-badge {
|
|
466
|
+
display: grid;
|
|
467
|
+
place-items: center;
|
|
468
|
+
width: 56px;
|
|
469
|
+
height: 56px;
|
|
470
|
+
border-radius: 999px;
|
|
471
|
+
background: var(--zrl-accent-soft);
|
|
472
|
+
color: var(--zrl-accent-ink);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.${PREFIX}-status {
|
|
476
|
+
display: flex;
|
|
477
|
+
align-items: center;
|
|
478
|
+
justify-content: center;
|
|
479
|
+
gap: 8px;
|
|
480
|
+
margin-top: 20px;
|
|
481
|
+
font-size: 14px;
|
|
482
|
+
font-weight: 500;
|
|
483
|
+
color: var(--zrl-ink);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.${PREFIX}-dot { position: relative; display: grid; place-items: center; width: 8px; height: 8px; }
|
|
487
|
+
.${PREFIX}-dot i {
|
|
488
|
+
position: absolute;
|
|
489
|
+
width: 8px;
|
|
490
|
+
height: 8px;
|
|
491
|
+
border-radius: 999px;
|
|
492
|
+
background: var(--zrl-accent);
|
|
493
|
+
font-style: normal;
|
|
494
|
+
}
|
|
495
|
+
.${PREFIX}-dot i:first-child { animation: ${PREFIX}-ping 1.8s cubic-bezier(0.23, 1, 0.32, 1) infinite; }
|
|
496
|
+
|
|
497
|
+
.${PREFIX}-timer {
|
|
498
|
+
margin: 4px 0 0;
|
|
499
|
+
font-size: 12px;
|
|
500
|
+
font-variant-numeric: tabular-nums;
|
|
501
|
+
color: var(--zrl-ink-mute);
|
|
502
|
+
transition: color 200ms ease-out;
|
|
503
|
+
}
|
|
504
|
+
.${PREFIX}-timer[data-urgent="true"] { color: var(--zrl-urgent); }
|
|
505
|
+
|
|
506
|
+
.${PREFIX}-help {
|
|
507
|
+
padding: 14px 24px;
|
|
508
|
+
border-top: 1px solid var(--zrl-line-soft);
|
|
509
|
+
background: var(--zrl-surface-sunken);
|
|
510
|
+
border-radius: 0;
|
|
511
|
+
}
|
|
512
|
+
.${PREFIX}-help-title { margin: 0; font-size: 12px; font-weight: 600; color: var(--zrl-ink); }
|
|
513
|
+
.${PREFIX}-help-body {
|
|
514
|
+
margin: 4px auto 0;
|
|
515
|
+
max-width: 34ch;
|
|
516
|
+
font-size: 12px;
|
|
517
|
+
line-height: 1.55;
|
|
518
|
+
color: var(--zrl-ink-soft);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.${PREFIX}-footer { padding: 12px; border-top: 1px solid var(--zrl-line-soft); }
|
|
522
|
+
|
|
523
|
+
.${PREFIX}-cancel {
|
|
524
|
+
display: block;
|
|
525
|
+
width: 100%;
|
|
526
|
+
padding: 10px;
|
|
527
|
+
border: 0;
|
|
528
|
+
border-radius: 12px;
|
|
529
|
+
background: transparent;
|
|
530
|
+
font: inherit;
|
|
531
|
+
font-size: 14px;
|
|
532
|
+
font-weight: 500;
|
|
533
|
+
color: var(--zrl-ink-soft);
|
|
534
|
+
cursor: pointer;
|
|
535
|
+
transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
|
|
536
|
+
}
|
|
537
|
+
.${PREFIX}-cancel:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
|
|
538
|
+
.${PREFIX}-cancel:active { transform: scale(0.99); }
|
|
539
|
+
|
|
540
|
+
.${PREFIX}-secured {
|
|
541
|
+
display: flex;
|
|
542
|
+
align-items: center;
|
|
543
|
+
justify-content: center;
|
|
544
|
+
gap: 6px;
|
|
545
|
+
margin: 6px 0 0;
|
|
546
|
+
font-size: 12px;
|
|
547
|
+
color: var(--zrl-ink-mute);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
.${PREFIX}-close {
|
|
551
|
+
position: absolute;
|
|
552
|
+
top: 12px;
|
|
553
|
+
inset-inline-end: 12px;
|
|
554
|
+
display: grid;
|
|
555
|
+
place-items: center;
|
|
556
|
+
width: 32px;
|
|
557
|
+
height: 32px;
|
|
558
|
+
padding: 0;
|
|
559
|
+
border: 0;
|
|
560
|
+
border-radius: 8px;
|
|
561
|
+
background: transparent;
|
|
562
|
+
color: var(--zrl-ink-mute);
|
|
563
|
+
cursor: pointer;
|
|
564
|
+
transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
|
|
565
|
+
}
|
|
566
|
+
.${PREFIX}-close:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
|
|
567
|
+
.${PREFIX}-close:active { transform: scale(0.95); }
|
|
568
|
+
|
|
569
|
+
.${PREFIX}-card :focus-visible {
|
|
570
|
+
outline: 2px solid var(--zrl-accent);
|
|
571
|
+
outline-offset: 2px;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
@keyframes ${PREFIX}-fade { from { opacity: 0 } to { opacity: 1 } }
|
|
575
|
+
@keyframes ${PREFIX}-rise {
|
|
576
|
+
from { opacity: 0; transform: translateY(10px) scale(0.98) }
|
|
577
|
+
to { opacity: 1; transform: none }
|
|
578
|
+
}
|
|
579
|
+
@keyframes ${PREFIX}-ping {
|
|
580
|
+
0% { transform: scale(1); opacity: 0.5 }
|
|
581
|
+
70%, 100% { transform: scale(2.6); opacity: 0 }
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
@media (prefers-reduced-motion: reduce) {
|
|
585
|
+
.${PREFIX}-scrim,
|
|
586
|
+
.${PREFIX}-card,
|
|
587
|
+
.${PREFIX}-qr-overlay { animation: none }
|
|
588
|
+
.${PREFIX}-dot i:first-child { animation: none; opacity: 0.35 }
|
|
589
|
+
.${PREFIX}-qr,
|
|
590
|
+
.${PREFIX}-cancel,
|
|
591
|
+
.${PREFIX}-close,
|
|
592
|
+
.${PREFIX}-timer { transition: none }
|
|
593
|
+
}
|
|
594
|
+
`;
|
|
595
|
+
function ensureStyles() {
|
|
596
|
+
if (typeof document === "undefined") return;
|
|
597
|
+
if (document.getElementById(STYLE_ELEMENT_ID)) return;
|
|
598
|
+
const el = document.createElement("style");
|
|
599
|
+
el.id = STYLE_ELEMENT_ID;
|
|
600
|
+
el.textContent = CSS;
|
|
601
|
+
document.head.appendChild(el);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// src/PairingModal.tsx
|
|
605
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
606
|
+
var DEFAULT_PAIRING_TIMEOUT_MS = 12e4;
|
|
607
|
+
var URGENT_SECONDS = 20;
|
|
608
|
+
function mmss(totalSeconds) {
|
|
609
|
+
const m = Math.floor(totalSeconds / 60);
|
|
610
|
+
const s = totalSeconds % 60;
|
|
611
|
+
return `${m}:${String(s).padStart(2, "0")}`;
|
|
612
|
+
}
|
|
613
|
+
var IconClose = () => /* @__PURE__ */ jsx3("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, focusable: "false", children: /* @__PURE__ */ jsx3("path", { d: "M18 6 6 18M6 6l12 12" }) });
|
|
614
|
+
var IconPhone = () => /* @__PURE__ */ jsxs3("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, focusable: "false", children: [
|
|
615
|
+
/* @__PURE__ */ jsx3("rect", { x: "6", y: "2", width: "12", height: "20", rx: "2.5" }),
|
|
616
|
+
/* @__PURE__ */ jsx3("path", { d: "M11 18.5h2" })
|
|
617
|
+
] });
|
|
618
|
+
var IconShield = () => /* @__PURE__ */ jsxs3("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, focusable: "false", children: [
|
|
619
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
|
|
620
|
+
/* @__PURE__ */ jsx3("path", { d: "m9 12 2 2 4-4" })
|
|
621
|
+
] });
|
|
622
|
+
function PairingModal({
|
|
623
|
+
state,
|
|
624
|
+
qrUrl,
|
|
625
|
+
onCancel,
|
|
626
|
+
locale,
|
|
627
|
+
theme = "auto",
|
|
628
|
+
timeoutMs = DEFAULT_PAIRING_TIMEOUT_MS
|
|
629
|
+
}) {
|
|
630
|
+
const t = strings(locale);
|
|
631
|
+
const titleId = useId();
|
|
632
|
+
const closeRef = useRef(null);
|
|
633
|
+
const deadlineRef = useRef(0);
|
|
634
|
+
const [remaining, setRemaining] = useState(Math.round(timeoutMs / 1e3));
|
|
635
|
+
const settled = state.status === "claimed" || state.status === "enrolling";
|
|
636
|
+
const onCancelRef = useRef(onCancel);
|
|
637
|
+
onCancelRef.current = onCancel;
|
|
638
|
+
useEffect(() => {
|
|
639
|
+
ensureStyles();
|
|
640
|
+
}, []);
|
|
641
|
+
useEffect(() => {
|
|
642
|
+
const serverMs = typeof state.expiresIn === "number" ? state.expiresIn * 1e3 : Infinity;
|
|
643
|
+
deadlineRef.current = Date.now() + Math.min(timeoutMs, serverMs);
|
|
644
|
+
setRemaining(Math.round(Math.min(timeoutMs, serverMs) / 1e3));
|
|
645
|
+
const id = setInterval(() => {
|
|
646
|
+
const left = Math.max(0, Math.ceil((deadlineRef.current - Date.now()) / 1e3));
|
|
647
|
+
setRemaining(left);
|
|
648
|
+
if (left === 0) {
|
|
649
|
+
clearInterval(id);
|
|
650
|
+
onCancelRef.current();
|
|
651
|
+
}
|
|
652
|
+
}, 1e3);
|
|
653
|
+
return () => clearInterval(id);
|
|
654
|
+
}, [timeoutMs]);
|
|
655
|
+
useEffect(() => {
|
|
656
|
+
const onKey = (e) => {
|
|
657
|
+
if (e.key === "Escape") onCancelRef.current();
|
|
658
|
+
};
|
|
659
|
+
document.addEventListener("keydown", onKey);
|
|
660
|
+
const previous = document.body.style.overflow;
|
|
661
|
+
document.body.style.overflow = "hidden";
|
|
662
|
+
closeRef.current?.focus();
|
|
663
|
+
return () => {
|
|
664
|
+
document.removeEventListener("keydown", onKey);
|
|
665
|
+
document.body.style.overflow = previous;
|
|
666
|
+
};
|
|
667
|
+
}, []);
|
|
668
|
+
if (typeof document === "undefined") return null;
|
|
669
|
+
const body = state.status === "enrolling" ? t.bodyEnrolling : settled ? t.bodyApprove : t.bodyScan;
|
|
670
|
+
return createPortal(
|
|
671
|
+
/* @__PURE__ */ jsx3("div", { className: `${cx("root")} ${cx("scrim")}`, "data-theme": theme, onClick: onCancel, children: /* @__PURE__ */ jsxs3(
|
|
672
|
+
"div",
|
|
673
|
+
{
|
|
674
|
+
className: cx("card"),
|
|
675
|
+
role: "dialog",
|
|
676
|
+
"aria-modal": "true",
|
|
677
|
+
"aria-labelledby": titleId,
|
|
678
|
+
dir: isRtl(locale) ? "rtl" : "ltr",
|
|
679
|
+
onClick: (e) => e.stopPropagation(),
|
|
680
|
+
children: [
|
|
681
|
+
/* @__PURE__ */ jsx3("button", { ref: closeRef, type: "button", className: cx("close"), "aria-label": t.close, onClick: onCancel, children: /* @__PURE__ */ jsx3(IconClose, {}) }),
|
|
682
|
+
/* @__PURE__ */ jsxs3("div", { className: cx("body"), children: [
|
|
683
|
+
/* @__PURE__ */ jsx3(ZorealLockup, { height: 44, className: cx("lockup") }),
|
|
684
|
+
/* @__PURE__ */ jsx3("h2", { id: titleId, className: cx("title"), children: settled ? t.titleApprove : t.title }),
|
|
685
|
+
/* @__PURE__ */ jsx3("p", { className: cx("body-text"), children: body }),
|
|
686
|
+
/* @__PURE__ */ jsxs3("div", { className: cx("qr-well"), children: [
|
|
687
|
+
/* @__PURE__ */ jsx3("img", { className: cx("qr"), "data-spent": settled, src: qrUrl, alt: t.qrAlt, width: 180, height: 180 }),
|
|
688
|
+
settled && /* @__PURE__ */ jsx3("span", { className: cx("qr-overlay"), children: /* @__PURE__ */ jsx3("span", { className: cx("qr-badge"), children: /* @__PURE__ */ jsx3(IconPhone, {}) }) })
|
|
689
|
+
] }),
|
|
690
|
+
/* @__PURE__ */ jsxs3("div", { className: cx("status"), children: [
|
|
691
|
+
/* @__PURE__ */ jsxs3("span", { className: cx("dot"), children: [
|
|
692
|
+
/* @__PURE__ */ jsx3("i", {}),
|
|
693
|
+
/* @__PURE__ */ jsx3("i", {})
|
|
694
|
+
] }),
|
|
695
|
+
settled ? t.waitingApproval : t.waiting
|
|
696
|
+
] }),
|
|
697
|
+
/* @__PURE__ */ jsx3("p", { className: cx("timer"), "data-urgent": remaining <= URGENT_SECONDS, children: interpolate(t.expiresIn, mmss(remaining)) })
|
|
698
|
+
] }),
|
|
699
|
+
/* @__PURE__ */ jsxs3("div", { className: cx("help"), children: [
|
|
700
|
+
/* @__PURE__ */ jsx3("p", { className: cx("help-title"), children: t.noIdTitle }),
|
|
701
|
+
/* @__PURE__ */ jsx3("p", { className: cx("help-body"), children: t.noIdBody })
|
|
702
|
+
] }),
|
|
703
|
+
/* @__PURE__ */ jsxs3("div", { className: cx("footer"), children: [
|
|
704
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: cx("cancel"), onClick: onCancel, children: t.cancel }),
|
|
705
|
+
/* @__PURE__ */ jsxs3("p", { className: cx("secured"), children: [
|
|
706
|
+
/* @__PURE__ */ jsx3(IconShield, {}),
|
|
707
|
+
t.secured
|
|
708
|
+
] })
|
|
709
|
+
] })
|
|
710
|
+
]
|
|
711
|
+
}
|
|
712
|
+
) }),
|
|
713
|
+
document.body
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
|
|
13
717
|
// src/context.tsx
|
|
14
|
-
import { jsx } from "react/jsx-runtime";
|
|
718
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
15
719
|
var ZorealOAuthContext = createContext(null);
|
|
720
|
+
var PairingHostContext = createContext(null);
|
|
721
|
+
function useZorealPairingHost() {
|
|
722
|
+
return useContext(PairingHostContext);
|
|
723
|
+
}
|
|
16
724
|
function ZorealOAuthProvider({
|
|
17
725
|
clientId,
|
|
18
726
|
issuer = DEFAULT_ISSUER,
|
|
19
727
|
locale,
|
|
728
|
+
theme = "auto",
|
|
729
|
+
pairingUI = "modal",
|
|
730
|
+
pairingTimeoutMs,
|
|
20
731
|
children
|
|
21
732
|
}) {
|
|
733
|
+
const [pairing, setPairing] = useState2(null);
|
|
22
734
|
const value = useMemo(
|
|
23
735
|
() => ({ clientId, issuer: issuer.replace(/\/$/, ""), locale }),
|
|
24
736
|
[clientId, issuer, locale]
|
|
25
737
|
);
|
|
26
|
-
|
|
738
|
+
const host = pairingUI === "modal" ? setPairing : null;
|
|
739
|
+
return /* @__PURE__ */ jsx4(ZorealOAuthContext.Provider, { value, children: /* @__PURE__ */ jsxs4(PairingHostContext.Provider, { value: host, children: [
|
|
740
|
+
children,
|
|
741
|
+
pairing && /* @__PURE__ */ jsx4(
|
|
742
|
+
PairingModal,
|
|
743
|
+
{
|
|
744
|
+
state: pairing.state,
|
|
745
|
+
qrUrl: pairing.qrUrl,
|
|
746
|
+
onCancel: pairing.cancel,
|
|
747
|
+
locale,
|
|
748
|
+
theme,
|
|
749
|
+
timeoutMs: pairingTimeoutMs
|
|
750
|
+
}
|
|
751
|
+
)
|
|
752
|
+
] }) });
|
|
27
753
|
}
|
|
28
754
|
function useZorealOAuth() {
|
|
29
755
|
const ctx = useContext(ZorealOAuthContext);
|
|
@@ -39,7 +765,7 @@ function useZorealOAuth() {
|
|
|
39
765
|
import { useMemo as useMemo2 } from "react";
|
|
40
766
|
|
|
41
767
|
// src/useZorealLogin.ts
|
|
42
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
768
|
+
import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
43
769
|
|
|
44
770
|
// src/jwt.ts
|
|
45
771
|
function unsafeClaims(idToken) {
|
|
@@ -193,11 +919,20 @@ function generateState() {
|
|
|
193
919
|
// src/useZorealLogin.ts
|
|
194
920
|
function useZorealFlow(options) {
|
|
195
921
|
const { clientId, issuer, locale } = useZorealOAuth();
|
|
196
|
-
const [pairing, setPairing] =
|
|
197
|
-
const
|
|
198
|
-
const
|
|
922
|
+
const [pairing, setPairing] = useState3(null);
|
|
923
|
+
const publish = useZorealPairingHost();
|
|
924
|
+
const publishRef = useRef2(publish);
|
|
925
|
+
publishRef.current = publish;
|
|
926
|
+
const abortRef = useRef2(null);
|
|
927
|
+
const optionsRef = useRef2(options);
|
|
199
928
|
optionsRef.current = options;
|
|
200
|
-
|
|
929
|
+
useEffect2(
|
|
930
|
+
() => () => {
|
|
931
|
+
abortRef.current?.abort();
|
|
932
|
+
publishRef.current?.(null);
|
|
933
|
+
},
|
|
934
|
+
[]
|
|
935
|
+
);
|
|
201
936
|
const login = useCallback(() => {
|
|
202
937
|
const opts = optionsRef.current;
|
|
203
938
|
const run = async () => {
|
|
@@ -232,6 +967,7 @@ function useZorealFlow(options) {
|
|
|
232
967
|
const cancel = () => {
|
|
233
968
|
controller.abort();
|
|
234
969
|
setPairing(null);
|
|
970
|
+
publishRef.current?.(null);
|
|
235
971
|
};
|
|
236
972
|
const surface = {
|
|
237
973
|
pairUrl: started.pair_url,
|
|
@@ -248,6 +984,9 @@ function useZorealFlow(options) {
|
|
|
248
984
|
cancel
|
|
249
985
|
};
|
|
250
986
|
setPairing(active);
|
|
987
|
+
if (!useAppLink) {
|
|
988
|
+
publishRef.current?.({ state: active.state, qrUrl: surface.qrUrl, cancel });
|
|
989
|
+
}
|
|
251
990
|
opts.onPairingStateChange?.(active.state);
|
|
252
991
|
if (useAppLink) {
|
|
253
992
|
window.location.assign(started.pair_url);
|
|
@@ -260,12 +999,16 @@ function useZorealFlow(options) {
|
|
|
260
999
|
setPairing(
|
|
261
1000
|
(p) => p && p.requestId === started.request_id ? { ...p, state: enriched } : p
|
|
262
1001
|
);
|
|
1002
|
+
if (!useAppLink) {
|
|
1003
|
+
publishRef.current?.({ state: enriched, qrUrl: surface.qrUrl, cancel });
|
|
1004
|
+
}
|
|
263
1005
|
opts.onPairingStateChange?.(enriched);
|
|
264
1006
|
},
|
|
265
1007
|
controller.signal
|
|
266
1008
|
);
|
|
267
1009
|
}
|
|
268
1010
|
setPairing(null);
|
|
1011
|
+
publishRef.current?.(null);
|
|
269
1012
|
if (flow === "auth-code") {
|
|
270
1013
|
opts.onCode?.({
|
|
271
1014
|
code,
|
|
@@ -291,6 +1034,7 @@ function useZorealFlow(options) {
|
|
|
291
1034
|
opts.onCredential?.(response);
|
|
292
1035
|
} catch (e) {
|
|
293
1036
|
setPairing(null);
|
|
1037
|
+
publishRef.current?.(null);
|
|
294
1038
|
if (e instanceof DOMException && e.name === "AbortError") return;
|
|
295
1039
|
if (e instanceof FlowAbandonedError) {
|
|
296
1040
|
opts.onNonOAuthError?.(e.reason);
|
|
@@ -326,7 +1070,7 @@ function useZorealLogin(options) {
|
|
|
326
1070
|
}
|
|
327
1071
|
|
|
328
1072
|
// src/ZorealLogin.tsx
|
|
329
|
-
import { jsx as
|
|
1073
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
330
1074
|
var TEXTS = {
|
|
331
1075
|
continue_with: "Continue with ZOREAL",
|
|
332
1076
|
signin_with: "Sign in with ZOREAL",
|
|
@@ -338,80 +1082,6 @@ var SIZES = {
|
|
|
338
1082
|
medium: { height: 38, font: 14, pad: 16 },
|
|
339
1083
|
small: { height: 32, font: 12, pad: 12 }
|
|
340
1084
|
};
|
|
341
|
-
var Mark = ({ size }) => /* @__PURE__ */ jsxs(
|
|
342
|
-
"svg",
|
|
343
|
-
{
|
|
344
|
-
width: size,
|
|
345
|
-
height: size,
|
|
346
|
-
viewBox: "8.4 7.4 62.2 62.2",
|
|
347
|
-
fill: "currentColor",
|
|
348
|
-
fillRule: "evenodd",
|
|
349
|
-
"aria-hidden": true,
|
|
350
|
-
focusable: "false",
|
|
351
|
-
children: [
|
|
352
|
-
/* @__PURE__ */ jsx2("path", { d: "M56.1,32.9c.6-3.1-.8-6.4-3.7-8.1l-18-10.4,5.2-3,15.4,8.9c5.4,3.1,7.7,9.6,5.8,15.3-.3.8-.6,1.6-1.1,2.4-.4.7-.9,1.4-1.5,2.1-1.3,1.4-2.9,2.6-4.6,3.3-3.6,1.5-7.9,1.4-11.6-.7l-8.9-5.1c-2.9-1.7-6.5-1.3-8.9.8-.6.6-1.2,1.2-1.7,2-.5.8-.8,1.7-.9,2.5-.6,3.1.9,6.4,3.7,8.1l18,10.4-5.2,3-15.4-8.9c-5.4-3.1-7.7-9.6-5.8-15.3.2-.8.6-1.6,1-2.4.5-.7,1-1.4,1.5-2.1,1.3-1.4,2.9-2.6,4.7-3.3,3.6-1.6,7.8-1.4,11.5.6l8.9,5.2c3,1.7,6.6,1.3,8.9-.8.6-.6,1.2-1.2,1.7-2,.4-.8.7-1.7.9-2.5Z" }),
|
|
353
|
-
/* @__PURE__ */ jsx2("path", { d: "M68.7,44.2c-.7,1.2-2.3,1.7-3.5.9-1.3-.7-1.7-2.3-1-3.5.7-1.3,2.3-1.7,3.5-1,1.3.7,1.7,2.3,1,3.6Z" }),
|
|
354
|
-
/* @__PURE__ */ jsx2("path", { d: "M25.6,21.3c5.1-.8,10.4,0,15.3,2.9l1.2.7h0c1.2.7,1.6,2.3.9,3.5s-2.3,1.7-3.5.9l-1.2-.7c-4.2-2.4-9.1-3-13.5-1.9-1.6.4-3.1,1.1-4.5,1.9h0c-1.2.7-2.8.3-3.5-1-.7-1.2-.3-2.8.9-3.5,0,0,.1,0,.3-.1.3-.1.6-.4,1-.5,2.1-1.1,4.4-1.7,6.7-2.2Z" }),
|
|
355
|
-
/* @__PURE__ */ jsx2("path", { d: "M9.6,31.8c.7-1.2,2.4-1.6,3.5-.8,1.2.7,1.6,2.4.8,3.5-.8,1.2-2.4,1.6-3.6.8-1.2-.8-1.5-2.4-.7-3.5Z" }),
|
|
356
|
-
/* @__PURE__ */ jsx2("path", { d: "M46.2,30.3c.7-1.3,2.3-1.7,3.5-1,1.2.7,1.7,2.3.9,3.6-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5Z" }),
|
|
357
|
-
/* @__PURE__ */ jsx2("path", { d: "M52.1,54.5c-5,.9-10.4,0-15.3-2.8l-1.2-.7h0c-1.2-.7-1.7-2.3-.9-3.5s2.3-1.7,3.5-.9l1.2.7c4.3,2.4,9.1,3,13.6,1.9,1.6-.4,3.1-1.1,4.5-1.9h0c1.2-.7,2.8-.3,3.5.9.7,1.3.3,2.9-.9,3.6-.1,0-.2,0-.3,0-.4.2-.7.4-1.1.6-2.1,1-4.3,1.7-6.7,2.1Z" }),
|
|
358
|
-
/* @__PURE__ */ jsx2("path", { d: "M31.4,45.6c-.7,1.2-2.3,1.7-3.5.9s-1.7-2.3-.9-3.5,2.3-1.7,3.5-.9,1.7,2.3.9,3.5Z" })
|
|
359
|
-
]
|
|
360
|
-
}
|
|
361
|
-
);
|
|
362
|
-
var PairingPanel = ({ pairing }) => {
|
|
363
|
-
const { status } = pairing.state;
|
|
364
|
-
const line = status === "claimed" ? "Approve the login in your ZOREAL ID app." : status === "enrolling" ? "Finishing enrolment. This screen will continue by itself." : pairing.appLink ? "Continue in the ZOREAL ID app, then return to this tab." : "Scan with your phone camera or the ZOREAL ID app.";
|
|
365
|
-
return /* @__PURE__ */ jsxs(
|
|
366
|
-
"div",
|
|
367
|
-
{
|
|
368
|
-
role: "dialog",
|
|
369
|
-
"aria-label": "Log in with ZOREAL",
|
|
370
|
-
style: {
|
|
371
|
-
marginTop: 8,
|
|
372
|
-
padding: 16,
|
|
373
|
-
width: 232,
|
|
374
|
-
borderRadius: 12,
|
|
375
|
-
border: "1px solid rgba(128,128,128,0.35)",
|
|
376
|
-
background: "Canvas",
|
|
377
|
-
color: "CanvasText",
|
|
378
|
-
textAlign: "center",
|
|
379
|
-
fontFamily: "inherit"
|
|
380
|
-
},
|
|
381
|
-
children: [
|
|
382
|
-
!pairing.appLink && /* @__PURE__ */ jsx2(
|
|
383
|
-
"img",
|
|
384
|
-
{
|
|
385
|
-
src: pairing.qrUrl,
|
|
386
|
-
alt: `QR code for ${pairing.pairUrl}`,
|
|
387
|
-
width: 200,
|
|
388
|
-
height: 200,
|
|
389
|
-
style: { display: "block", margin: "0 auto", borderRadius: 8 }
|
|
390
|
-
}
|
|
391
|
-
),
|
|
392
|
-
/* @__PURE__ */ jsx2("p", { style: { margin: "10px 0 0", fontSize: 12, lineHeight: 1.5 }, children: line }),
|
|
393
|
-
/* @__PURE__ */ jsx2(
|
|
394
|
-
"button",
|
|
395
|
-
{
|
|
396
|
-
type: "button",
|
|
397
|
-
onClick: pairing.cancel,
|
|
398
|
-
style: {
|
|
399
|
-
marginTop: 10,
|
|
400
|
-
border: "none",
|
|
401
|
-
background: "none",
|
|
402
|
-
color: "inherit",
|
|
403
|
-
opacity: 0.6,
|
|
404
|
-
fontSize: 12,
|
|
405
|
-
cursor: "pointer",
|
|
406
|
-
textDecoration: "underline"
|
|
407
|
-
},
|
|
408
|
-
children: "Cancel"
|
|
409
|
-
}
|
|
410
|
-
)
|
|
411
|
-
]
|
|
412
|
-
}
|
|
413
|
-
);
|
|
414
|
-
};
|
|
415
1085
|
function ZorealLogin(props) {
|
|
416
1086
|
const {
|
|
417
1087
|
onSuccess,
|
|
@@ -427,7 +1097,7 @@ function ZorealLogin(props) {
|
|
|
427
1097
|
click_listener,
|
|
428
1098
|
...request
|
|
429
1099
|
} = props;
|
|
430
|
-
const { login
|
|
1100
|
+
const { login } = useZorealFlow({
|
|
431
1101
|
...request,
|
|
432
1102
|
flow: "browser-direct",
|
|
433
1103
|
onCredential: onSuccess,
|
|
@@ -453,28 +1123,25 @@ function ZorealLogin(props) {
|
|
|
453
1123
|
}),
|
|
454
1124
|
[logo_alignment, s, shape, theme, width]
|
|
455
1125
|
);
|
|
456
|
-
return /* @__PURE__ */
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
),
|
|
472
|
-
internals.pairing && !internals.pairing.appLink && /* @__PURE__ */ jsx2(PairingPanel, { pairing: internals.pairing })
|
|
473
|
-
] });
|
|
1126
|
+
return /* @__PURE__ */ jsx5("div", { ...containerProps, children: /* @__PURE__ */ jsxs5(
|
|
1127
|
+
"button",
|
|
1128
|
+
{
|
|
1129
|
+
type: "button",
|
|
1130
|
+
style,
|
|
1131
|
+
onClick: () => {
|
|
1132
|
+
click_listener?.();
|
|
1133
|
+
login();
|
|
1134
|
+
},
|
|
1135
|
+
children: [
|
|
1136
|
+
/* @__PURE__ */ jsx5(ZorealMark, { size: Math.round(s.font * 1.25) }),
|
|
1137
|
+
type === "standard" && TEXTS[text]
|
|
1138
|
+
]
|
|
1139
|
+
}
|
|
1140
|
+
) });
|
|
474
1141
|
}
|
|
475
1142
|
|
|
476
1143
|
// src/useZorealAutoLogin.ts
|
|
477
|
-
import { useEffect as
|
|
1144
|
+
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
478
1145
|
function useZorealAutoLogin(options) {
|
|
479
1146
|
const { login } = useZorealFlow({
|
|
480
1147
|
flow: "browser-direct",
|
|
@@ -491,8 +1158,8 @@ function useZorealAutoLogin(options) {
|
|
|
491
1158
|
},
|
|
492
1159
|
onNonOAuthError: (e) => options.onError?.(e)
|
|
493
1160
|
});
|
|
494
|
-
const fired =
|
|
495
|
-
|
|
1161
|
+
const fired = useRef3(false);
|
|
1162
|
+
useEffect3(() => {
|
|
496
1163
|
if (options.disabled || fired.current) return;
|
|
497
1164
|
fired.current = true;
|
|
498
1165
|
login();
|
|
@@ -513,6 +1180,8 @@ function hasGrantedAnyScopeZoreal(response, firstScope, ...restScopes) {
|
|
|
513
1180
|
return [firstScope, ...restScopes].some((s) => granted.has(s));
|
|
514
1181
|
}
|
|
515
1182
|
export {
|
|
1183
|
+
DEFAULT_PAIRING_TIMEOUT_MS,
|
|
1184
|
+
PairingModal,
|
|
516
1185
|
ZorealLogin,
|
|
517
1186
|
ZorealOAuthProvider,
|
|
518
1187
|
hasGrantedAllScopesZoreal,
|