@zoreal/oauth2-react 0.1.11 → 0.2.5
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 +87 -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.cjs
CHANGED
|
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
+
DEFAULT_PAIRING_TIMEOUT_MS: () => DEFAULT_PAIRING_TIMEOUT_MS,
|
|
25
|
+
PairingModal: () => PairingModal,
|
|
24
26
|
ZorealLogin: () => ZorealLogin,
|
|
25
27
|
ZorealOAuthProvider: () => ZorealOAuthProvider,
|
|
26
28
|
hasGrantedAllScopesZoreal: () => hasGrantedAllScopesZoreal,
|
|
@@ -33,32 +35,758 @@ __export(index_exports, {
|
|
|
33
35
|
module.exports = __toCommonJS(index_exports);
|
|
34
36
|
|
|
35
37
|
// src/context.tsx
|
|
36
|
-
var
|
|
38
|
+
var import_react2 = require("react");
|
|
37
39
|
|
|
38
40
|
// src/wire.ts
|
|
39
41
|
var WIRE_VERSION = 1;
|
|
40
|
-
var SDK_VERSION = "0.
|
|
42
|
+
var SDK_VERSION = "0.2.5";
|
|
41
43
|
var DEFAULT_ISSUER = "https://id.zoreal.com";
|
|
42
44
|
var POLL_INTERVAL_MS = 2e3;
|
|
43
45
|
var POLL_INTERVAL_ENROLLING_MS = 5e3;
|
|
44
46
|
|
|
45
|
-
// src/
|
|
47
|
+
// src/PairingModal.tsx
|
|
48
|
+
var import_react = require("react");
|
|
49
|
+
var import_react_dom = require("react-dom");
|
|
50
|
+
|
|
51
|
+
// src/mark.tsx
|
|
46
52
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
47
|
-
var
|
|
53
|
+
var ZOREAL_BLUE = "#00b4d9";
|
|
54
|
+
function ZorealMark({
|
|
55
|
+
size = 18,
|
|
56
|
+
brand = false,
|
|
57
|
+
className
|
|
58
|
+
}) {
|
|
59
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
60
|
+
"svg",
|
|
61
|
+
{
|
|
62
|
+
width: size,
|
|
63
|
+
height: size,
|
|
64
|
+
viewBox: "8.4 7.4 62.2 62.2",
|
|
65
|
+
fill: brand ? ZOREAL_BLUE : "currentColor",
|
|
66
|
+
fillRule: "evenodd",
|
|
67
|
+
"aria-hidden": true,
|
|
68
|
+
focusable: "false",
|
|
69
|
+
className,
|
|
70
|
+
children: [
|
|
71
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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" }),
|
|
72
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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" }),
|
|
73
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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" }),
|
|
74
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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" }),
|
|
75
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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" }),
|
|
76
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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" }),
|
|
77
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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" })
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/lockup.tsx
|
|
84
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
85
|
+
function ZorealLockup({ height = 22, className }) {
|
|
86
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
87
|
+
"svg",
|
|
88
|
+
{
|
|
89
|
+
height,
|
|
90
|
+
width: height * (240 / 58.5),
|
|
91
|
+
viewBox: "0 0 240 58.5",
|
|
92
|
+
role: "img",
|
|
93
|
+
"aria-label": "ZOREAL",
|
|
94
|
+
focusable: "false",
|
|
95
|
+
className,
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
98
|
+
"path",
|
|
99
|
+
{
|
|
100
|
+
fill: "currentColor",
|
|
101
|
+
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"
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { fill: ZOREAL_BLUE, fillRule: "evenodd", children: [
|
|
105
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
|
|
106
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
|
|
107
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
|
|
109
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
|
|
110
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
|
|
111
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
|
|
112
|
+
] })
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/i18n.ts
|
|
119
|
+
var en = {
|
|
120
|
+
title: "Scan to sign in",
|
|
121
|
+
titleApprove: "Approve on your phone",
|
|
122
|
+
bodyScan: "Scan with your phone camera or the ZOREAL ID app.",
|
|
123
|
+
bodyApprove: "Approve the login in your ZOREAL ID app.",
|
|
124
|
+
bodyEnrolling: "Finish setting up ZOREAL ID on your phone, then approve the login.",
|
|
125
|
+
waiting: "Waiting for scan",
|
|
126
|
+
waitingApproval: "Waiting for approval",
|
|
127
|
+
expiresIn: "Expires in {time}",
|
|
128
|
+
secured: "Proof-of-Human verification by ZOREAL",
|
|
129
|
+
noIdTitle: "No ZOREAL ID yet?",
|
|
130
|
+
noIdBody: "Scan the same code to download the app and create one for free. It only takes a minute.",
|
|
131
|
+
cancel: "Cancel",
|
|
132
|
+
close: "Close",
|
|
133
|
+
qrAlt: "QR code to sign in with ZOREAL"
|
|
134
|
+
};
|
|
135
|
+
var TRANSLATIONS = {
|
|
136
|
+
en,
|
|
137
|
+
sv: {
|
|
138
|
+
title: "Skanna f\xF6r att logga in",
|
|
139
|
+
titleApprove: "Godk\xE4nn p\xE5 telefonen",
|
|
140
|
+
bodyScan: "Skanna med telefonens kamera eller ZOREAL ID-appen.",
|
|
141
|
+
bodyApprove: "Godk\xE4nn inloggningen i ZOREAL ID-appen.",
|
|
142
|
+
bodyEnrolling: "Slutf\xF6r konfigurationen av ZOREAL ID p\xE5 telefonen och godk\xE4nn sedan inloggningen.",
|
|
143
|
+
waiting: "V\xE4ntar p\xE5 skanning",
|
|
144
|
+
waitingApproval: "V\xE4ntar p\xE5 godk\xE4nnande",
|
|
145
|
+
expiresIn: "Upph\xF6r om {time}",
|
|
146
|
+
secured: "Proof-of-Human-verifiering av ZOREAL",
|
|
147
|
+
noIdTitle: "Har du inget ZOREAL ID?",
|
|
148
|
+
noIdBody: "Skanna samma kod f\xF6r att ladda ner appen och skapa ett gratis. Det tar bara en minut.",
|
|
149
|
+
cancel: "Avbryt",
|
|
150
|
+
close: "St\xE4ng",
|
|
151
|
+
qrAlt: "QR-kod f\xF6r att logga in med ZOREAL"
|
|
152
|
+
},
|
|
153
|
+
es: {
|
|
154
|
+
title: "Escanea para iniciar sesi\xF3n",
|
|
155
|
+
titleApprove: "Apru\xE9balo en tu tel\xE9fono",
|
|
156
|
+
bodyScan: "Escanea con la c\xE1mara de tu tel\xE9fono o con la app ZOREAL ID.",
|
|
157
|
+
bodyApprove: "Aprueba el inicio de sesi\xF3n en tu app ZOREAL ID.",
|
|
158
|
+
bodyEnrolling: "Termina de configurar ZOREAL ID en tu tel\xE9fono y luego aprueba el inicio de sesi\xF3n.",
|
|
159
|
+
waiting: "Esperando el escaneo",
|
|
160
|
+
waitingApproval: "Esperando aprobaci\xF3n",
|
|
161
|
+
expiresIn: "Caduca en {time}",
|
|
162
|
+
secured: "Verificaci\xF3n Proof-of-Human de ZOREAL",
|
|
163
|
+
noIdTitle: "\xBFA\xFAn no tienes ZOREAL ID?",
|
|
164
|
+
noIdBody: "Escanea el mismo c\xF3digo para descargar la app y crear una gratis. Solo toma un minuto.",
|
|
165
|
+
cancel: "Cancelar",
|
|
166
|
+
close: "Cerrar",
|
|
167
|
+
qrAlt: "C\xF3digo QR para iniciar sesi\xF3n con ZOREAL"
|
|
168
|
+
},
|
|
169
|
+
pt: {
|
|
170
|
+
title: "Digitalize para entrar",
|
|
171
|
+
titleApprove: "Aprove no seu telefone",
|
|
172
|
+
bodyScan: "Digitalize com a c\xE2mera do seu telefone ou com o app ZOREAL ID.",
|
|
173
|
+
bodyApprove: "Aprove o login no app ZOREAL ID.",
|
|
174
|
+
bodyEnrolling: "Termine de configurar o ZOREAL ID no seu telefone e depois aprove o login.",
|
|
175
|
+
waiting: "Aguardando digitaliza\xE7\xE3o",
|
|
176
|
+
waitingApproval: "Aguardando aprova\xE7\xE3o",
|
|
177
|
+
expiresIn: "Expira em {time}",
|
|
178
|
+
secured: "Verifica\xE7\xE3o Proof-of-Human da ZOREAL",
|
|
179
|
+
noIdTitle: "Ainda n\xE3o tem ZOREAL ID?",
|
|
180
|
+
noIdBody: "Digitalize o mesmo c\xF3digo para baixar o app e criar uma conta gr\xE1tis. Leva s\xF3 um minuto.",
|
|
181
|
+
cancel: "Cancelar",
|
|
182
|
+
close: "Fechar",
|
|
183
|
+
qrAlt: "C\xF3digo QR para entrar com ZOREAL"
|
|
184
|
+
},
|
|
185
|
+
fr: {
|
|
186
|
+
title: "Scannez pour vous connecter",
|
|
187
|
+
titleApprove: "Approuvez sur votre t\xE9l\xE9phone",
|
|
188
|
+
bodyScan: "Scannez avec l'appareil photo de votre t\xE9l\xE9phone ou l'app ZOREAL ID.",
|
|
189
|
+
bodyApprove: "Approuvez la connexion dans votre app ZOREAL ID.",
|
|
190
|
+
bodyEnrolling: "Terminez la configuration de ZOREAL ID sur votre t\xE9l\xE9phone, puis approuvez la connexion.",
|
|
191
|
+
waiting: "En attente du scan",
|
|
192
|
+
waitingApproval: "En attente d'approbation",
|
|
193
|
+
expiresIn: "Expire dans {time}",
|
|
194
|
+
secured: "V\xE9rification Proof-of-Human par ZOREAL",
|
|
195
|
+
noIdTitle: "Pas encore de ZOREAL ID ?",
|
|
196
|
+
noIdBody: "Scannez le m\xEAme code pour t\xE9l\xE9charger l'app et en cr\xE9er un gratuitement. Cela prend une minute.",
|
|
197
|
+
cancel: "Annuler",
|
|
198
|
+
close: "Fermer",
|
|
199
|
+
qrAlt: "Code QR pour se connecter avec ZOREAL"
|
|
200
|
+
},
|
|
201
|
+
de: {
|
|
202
|
+
title: "Zum Anmelden scannen",
|
|
203
|
+
titleApprove: "Auf dem Handy best\xE4tigen",
|
|
204
|
+
bodyScan: "Mit der Handykamera oder der ZOREAL ID App scannen.",
|
|
205
|
+
bodyApprove: "Anmeldung in der ZOREAL ID App best\xE4tigen.",
|
|
206
|
+
bodyEnrolling: "ZOREAL ID auf dem Handy fertig einrichten und dann die Anmeldung best\xE4tigen.",
|
|
207
|
+
waiting: "Warten auf Scan",
|
|
208
|
+
waitingApproval: "Warten auf Best\xE4tigung",
|
|
209
|
+
expiresIn: "L\xE4uft ab in {time}",
|
|
210
|
+
secured: "Proof-of-Human-Verifizierung von ZOREAL",
|
|
211
|
+
noIdTitle: "Noch keine ZOREAL ID?",
|
|
212
|
+
noIdBody: "Denselben Code scannen, um die App zu laden und kostenlos eine zu erstellen. Dauert nur eine Minute.",
|
|
213
|
+
cancel: "Abbrechen",
|
|
214
|
+
close: "Schlie\xDFen",
|
|
215
|
+
qrAlt: "QR-Code f\xFCr die Anmeldung mit ZOREAL"
|
|
216
|
+
},
|
|
217
|
+
ru: {
|
|
218
|
+
title: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435, \u0447\u0442\u043E\u0431\u044B \u0432\u043E\u0439\u0442\u0438",
|
|
219
|
+
titleApprove: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0435",
|
|
220
|
+
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.",
|
|
221
|
+
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.",
|
|
222
|
+
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.",
|
|
223
|
+
waiting: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u0441\u043A\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F",
|
|
224
|
+
waitingApproval: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F",
|
|
225
|
+
expiresIn: "\u0418\u0441\u0442\u0435\u043A\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 {time}",
|
|
226
|
+
secured: "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 Proof-of-Human \u043E\u0442 ZOREAL",
|
|
227
|
+
noIdTitle: "\u0415\u0449\u0451 \u043D\u0435\u0442 ZOREAL ID?",
|
|
228
|
+
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.",
|
|
229
|
+
cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
|
|
230
|
+
close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
|
|
231
|
+
qrAlt: "QR-\u043A\u043E\u0434 \u0434\u043B\u044F \u0432\u0445\u043E\u0434\u0430 \u0447\u0435\u0440\u0435\u0437 ZOREAL"
|
|
232
|
+
},
|
|
233
|
+
ja: {
|
|
234
|
+
title: "\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30ED\u30B0\u30A4\u30F3",
|
|
235
|
+
titleApprove: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3067\u627F\u8A8D",
|
|
236
|
+
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",
|
|
237
|
+
bodyApprove: "ZOREAL ID\u30A2\u30D7\u30EA\u3067\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
238
|
+
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",
|
|
239
|
+
waiting: "\u30B9\u30AD\u30E3\u30F3\u5F85\u3061",
|
|
240
|
+
waitingApproval: "\u627F\u8A8D\u5F85\u3061",
|
|
241
|
+
expiresIn: "\u6709\u52B9\u671F\u9650\u307E\u3067 {time}",
|
|
242
|
+
secured: "ZOREAL\u306B\u3088\u308BProof-of-Human\u8A8D\u8A3C",
|
|
243
|
+
noIdTitle: "ZOREAL ID\u3092\u304A\u6301\u3061\u3067\u306A\u3044\u3067\u3059\u304B\uFF1F",
|
|
244
|
+
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",
|
|
245
|
+
cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
|
|
246
|
+
close: "\u9589\u3058\u308B",
|
|
247
|
+
qrAlt: "ZOREAL\u3067\u30ED\u30B0\u30A4\u30F3\u3059\u308B\u305F\u3081\u306EQR\u30B3\u30FC\u30C9"
|
|
248
|
+
},
|
|
249
|
+
hi: {
|
|
250
|
+
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",
|
|
251
|
+
titleApprove: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u092A\u0930 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902",
|
|
252
|
+
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",
|
|
253
|
+
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",
|
|
254
|
+
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",
|
|
255
|
+
waiting: "\u0938\u094D\u0915\u0948\u0928 \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
|
|
256
|
+
waitingApproval: "\u0938\u094D\u0935\u0940\u0915\u0943\u0924\u093F \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
|
|
257
|
+
expiresIn: "{time} \u092E\u0947\u0902 \u0938\u092E\u093E\u092A\u094D\u0924",
|
|
258
|
+
secured: "ZOREAL \u0926\u094D\u0935\u093E\u0930\u093E Proof-of-Human \u0938\u0924\u094D\u092F\u093E\u092A\u0928",
|
|
259
|
+
noIdTitle: "\u0905\u092D\u0940 \u0924\u0915 ZOREAL ID \u0928\u0939\u0940\u0902 \u0939\u0948?",
|
|
260
|
+
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",
|
|
261
|
+
cancel: "\u0930\u0926\u094D\u0926 \u0915\u0930\u0947\u0902",
|
|
262
|
+
close: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
|
|
263
|
+
qrAlt: "ZOREAL \u0938\u0947 \u0938\u093E\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F QR \u0915\u094B\u0921"
|
|
264
|
+
},
|
|
265
|
+
zhs: {
|
|
266
|
+
title: "\u626B\u7801\u767B\u5F55",
|
|
267
|
+
titleApprove: "\u5728\u624B\u673A\u4E0A\u6279\u51C6",
|
|
268
|
+
bodyScan: "\u4F7F\u7528\u624B\u673A\u76F8\u673A\u6216 ZOREAL ID \u5E94\u7528\u626B\u63CF\u3002",
|
|
269
|
+
bodyApprove: "\u8BF7\u5728 ZOREAL ID \u5E94\u7528\u4E2D\u6279\u51C6\u767B\u5F55\u3002",
|
|
270
|
+
bodyEnrolling: "\u8BF7\u5728\u624B\u673A\u4E0A\u5B8C\u6210 ZOREAL ID \u8BBE\u7F6E\uFF0C\u7136\u540E\u6279\u51C6\u767B\u5F55\u3002",
|
|
271
|
+
waiting: "\u7B49\u5F85\u626B\u63CF",
|
|
272
|
+
waitingApproval: "\u7B49\u5F85\u6279\u51C6",
|
|
273
|
+
expiresIn: "{time} \u540E\u5931\u6548",
|
|
274
|
+
secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A8C\u8BC1",
|
|
275
|
+
noIdTitle: "\u8FD8\u6CA1\u6709 ZOREAL ID\uFF1F",
|
|
276
|
+
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",
|
|
277
|
+
cancel: "\u53D6\u6D88",
|
|
278
|
+
close: "\u5173\u95ED",
|
|
279
|
+
qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5F55\u7684\u4E8C\u7EF4\u7801"
|
|
280
|
+
},
|
|
281
|
+
zht: {
|
|
282
|
+
title: "\u6383\u78BC\u767B\u5165",
|
|
283
|
+
titleApprove: "\u5728\u624B\u6A5F\u4E0A\u6838\u51C6",
|
|
284
|
+
bodyScan: "\u4F7F\u7528\u624B\u6A5F\u76F8\u6A5F\u6216 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u6383\u63CF\u3002",
|
|
285
|
+
bodyApprove: "\u8ACB\u5728 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u4E2D\u6838\u51C6\u767B\u5165\u3002",
|
|
286
|
+
bodyEnrolling: "\u8ACB\u5728\u624B\u6A5F\u4E0A\u5B8C\u6210 ZOREAL ID \u8A2D\u5B9A\uFF0C\u7136\u5F8C\u6838\u51C6\u767B\u5165\u3002",
|
|
287
|
+
waiting: "\u7B49\u5F85\u6383\u63CF",
|
|
288
|
+
waitingApproval: "\u7B49\u5F85\u6838\u51C6",
|
|
289
|
+
expiresIn: "{time} \u5F8C\u5931\u6548",
|
|
290
|
+
secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A57\u8B49",
|
|
291
|
+
noIdTitle: "\u9084\u6C92\u6709 ZOREAL ID\uFF1F",
|
|
292
|
+
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",
|
|
293
|
+
cancel: "\u53D6\u6D88",
|
|
294
|
+
close: "\u95DC\u9589",
|
|
295
|
+
qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5165\u7684 QR code"
|
|
296
|
+
},
|
|
297
|
+
ar: {
|
|
298
|
+
title: "\u0627\u0645\u0633\u062D \u0644\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644",
|
|
299
|
+
titleApprove: "\u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u0647\u0627\u062A\u0641\u0643",
|
|
300
|
+
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.",
|
|
301
|
+
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.",
|
|
302
|
+
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.",
|
|
303
|
+
waiting: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0633\u062D",
|
|
304
|
+
waitingApproval: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0648\u0627\u0641\u0642\u0629",
|
|
305
|
+
expiresIn: "\u062A\u0646\u062A\u0647\u064A \u0627\u0644\u0635\u0644\u0627\u062D\u064A\u0629 \u062E\u0644\u0627\u0644 {time}",
|
|
306
|
+
secured: "\u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 Proof-of-Human \u0628\u0648\u0627\u0633\u0637\u0629 ZOREAL",
|
|
307
|
+
noIdTitle: "\u0644\u064A\u0633 \u0644\u062F\u064A\u0643 ZOREAL ID \u0628\u0639\u062F\u061F",
|
|
308
|
+
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.",
|
|
309
|
+
cancel: "\u0625\u0644\u063A\u0627\u0621",
|
|
310
|
+
close: "\u0625\u063A\u0644\u0627\u0642",
|
|
311
|
+
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"
|
|
312
|
+
},
|
|
313
|
+
ko: {
|
|
314
|
+
title: "\uC2A4\uCE94\uD558\uC5EC \uB85C\uADF8\uC778",
|
|
315
|
+
titleApprove: "\uD734\uB300\uD3F0\uC5D0\uC11C \uC2B9\uC778",
|
|
316
|
+
bodyScan: "\uD734\uB300\uD3F0 \uCE74\uBA54\uB77C \uB610\uB294 ZOREAL ID \uC571\uC73C\uB85C \uC2A4\uCE94\uD558\uC138\uC694.",
|
|
317
|
+
bodyApprove: "ZOREAL ID \uC571\uC5D0\uC11C \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
|
|
318
|
+
bodyEnrolling: "\uD734\uB300\uD3F0\uC5D0\uC11C ZOREAL ID \uC124\uC815\uC744 \uC644\uB8CC\uD55C \uD6C4 \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
|
|
319
|
+
waiting: "\uC2A4\uCE94 \uB300\uAE30 \uC911",
|
|
320
|
+
waitingApproval: "\uC2B9\uC778 \uB300\uAE30 \uC911",
|
|
321
|
+
expiresIn: "{time} \uD6C4 \uB9CC\uB8CC",
|
|
322
|
+
secured: "ZOREAL\uC758 Proof-of-Human \uC778\uC99D",
|
|
323
|
+
noIdTitle: "\uC544\uC9C1 ZOREAL ID\uAC00 \uC5C6\uC73C\uC2E0\uAC00\uC694?",
|
|
324
|
+
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.",
|
|
325
|
+
cancel: "\uCDE8\uC18C",
|
|
326
|
+
close: "\uB2EB\uAE30",
|
|
327
|
+
qrAlt: "ZOREAL\uB85C \uB85C\uADF8\uC778\uD558\uAE30 \uC704\uD55C QR \uCF54\uB4DC"
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
var RTL = /* @__PURE__ */ new Set(["ar", "he", "fa", "ur"]);
|
|
331
|
+
function lookup(locale) {
|
|
332
|
+
const tag = locale.toLowerCase().replace(/_/g, "-");
|
|
333
|
+
const primary = tag.split("-")[0];
|
|
334
|
+
if (primary === "zh") {
|
|
335
|
+
const simplified = /(^|-)(hans|cn|sg|my)(-|$)/.test(tag);
|
|
336
|
+
return TRANSLATIONS[simplified ? "zhs" : "zht"];
|
|
337
|
+
}
|
|
338
|
+
return TRANSLATIONS[tag] ?? TRANSLATIONS[primary];
|
|
339
|
+
}
|
|
340
|
+
function browserLocales() {
|
|
341
|
+
if (typeof navigator === "undefined") return [];
|
|
342
|
+
const nav = navigator;
|
|
343
|
+
if (nav.languages && nav.languages.length) return [...nav.languages];
|
|
344
|
+
return nav.language ? [nav.language] : [];
|
|
345
|
+
}
|
|
346
|
+
function strings(locale) {
|
|
347
|
+
if (locale) return lookup(locale) ?? en;
|
|
348
|
+
for (const candidate of browserLocales()) {
|
|
349
|
+
const hit = lookup(candidate);
|
|
350
|
+
if (hit) return hit;
|
|
351
|
+
}
|
|
352
|
+
return en;
|
|
353
|
+
}
|
|
354
|
+
function isRtl(locale) {
|
|
355
|
+
const tag = locale ?? browserLocales()[0];
|
|
356
|
+
if (!tag) return false;
|
|
357
|
+
return RTL.has(tag.toLowerCase().replace(/_/g, "-").split("-")[0]);
|
|
358
|
+
}
|
|
359
|
+
function interpolate(template, time) {
|
|
360
|
+
return template.replace("{time}", time);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/styles.ts
|
|
364
|
+
var PREFIX = "zrl";
|
|
365
|
+
var cx = (name) => `${PREFIX}-${name}`;
|
|
366
|
+
var STYLE_ELEMENT_ID = "zoreal-pairing-styles";
|
|
367
|
+
var LIGHT = `
|
|
368
|
+
--zrl-scrim: rgba(16, 18, 27, 0.45);
|
|
369
|
+
--zrl-surface: #ffffff;
|
|
370
|
+
--zrl-surface-sunken: #f6f7f9;
|
|
371
|
+
--zrl-ink: #16181c;
|
|
372
|
+
--zrl-ink-soft: #4a4f57;
|
|
373
|
+
--zrl-ink-mute: #6b7078;
|
|
374
|
+
--zrl-line: #e4e6ea;
|
|
375
|
+
--zrl-line-soft: #eef0f3;
|
|
376
|
+
--zrl-accent: #00b4d9;
|
|
377
|
+
--zrl-accent-soft: #dcf3fa;
|
|
378
|
+
--zrl-accent-ink: #04698a;
|
|
379
|
+
--zrl-urgent: #b4761a;
|
|
380
|
+
--zrl-qr-bg: #ffffff;
|
|
381
|
+
--zrl-shadow: 0 1px 2px rgba(16, 18, 27, 0.06), 0 20px 50px -12px rgba(16, 18, 27, 0.3);
|
|
382
|
+
--zrl-ring: rgba(16, 18, 27, 0.07);
|
|
383
|
+
`;
|
|
384
|
+
var DARK = `
|
|
385
|
+
--zrl-scrim: rgba(0, 0, 0, 0.62);
|
|
386
|
+
--zrl-surface: #17191d;
|
|
387
|
+
--zrl-surface-sunken: #1f2226;
|
|
388
|
+
--zrl-ink: #f4f5f7;
|
|
389
|
+
--zrl-ink-soft: #b3b8c0;
|
|
390
|
+
--zrl-ink-mute: #8b9199;
|
|
391
|
+
--zrl-line: #2c3036;
|
|
392
|
+
--zrl-line-soft: #24272c;
|
|
393
|
+
--zrl-accent: #34c9e8;
|
|
394
|
+
--zrl-accent-soft: #0d3b47;
|
|
395
|
+
--zrl-accent-ink: #7fdcf0;
|
|
396
|
+
--zrl-urgent: #e0a952;
|
|
397
|
+
/* The QR well stays white in dark mode on purpose: a scanner needs the
|
|
398
|
+
quiet-zone contrast, and an inverted QR fails on a good number of phone
|
|
399
|
+
cameras. It reads as a deliberate light panel, not a theming miss. */
|
|
400
|
+
--zrl-qr-bg: #ffffff;
|
|
401
|
+
--zrl-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 20px 50px -12px rgba(0, 0, 0, 0.65);
|
|
402
|
+
--zrl-ring: rgba(255, 255, 255, 0.1);
|
|
403
|
+
`;
|
|
404
|
+
var CSS = `
|
|
405
|
+
.${PREFIX}-root { ${LIGHT} }
|
|
406
|
+
.${PREFIX}-root[data-theme="dark"] { ${DARK} }
|
|
407
|
+
@media (prefers-color-scheme: dark) {
|
|
408
|
+
.${PREFIX}-root[data-theme="auto"] { ${DARK} }
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.${PREFIX}-scrim {
|
|
412
|
+
position: fixed;
|
|
413
|
+
inset: 0;
|
|
414
|
+
z-index: 2147483000;
|
|
415
|
+
display: grid;
|
|
416
|
+
place-items: center;
|
|
417
|
+
overflow-y: auto;
|
|
418
|
+
padding: 16px;
|
|
419
|
+
background: var(--zrl-scrim);
|
|
420
|
+
backdrop-filter: blur(3px);
|
|
421
|
+
-webkit-backdrop-filter: blur(3px);
|
|
422
|
+
font-family: inherit;
|
|
423
|
+
animation: ${PREFIX}-fade 200ms ease-out both;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.${PREFIX}-card {
|
|
427
|
+
position: relative;
|
|
428
|
+
box-sizing: border-box;
|
|
429
|
+
width: 100%;
|
|
430
|
+
max-width: 380px;
|
|
431
|
+
border-radius: 16px;
|
|
432
|
+
background: var(--zrl-surface);
|
|
433
|
+
color: var(--zrl-ink);
|
|
434
|
+
box-shadow: var(--zrl-shadow);
|
|
435
|
+
outline: 1px solid var(--zrl-ring);
|
|
436
|
+
outline-offset: -1px;
|
|
437
|
+
text-align: center;
|
|
438
|
+
animation: ${PREFIX}-rise 300ms cubic-bezier(0.23, 1, 0.32, 1) both;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.${PREFIX}-body { padding: 28px 24px 20px; }
|
|
442
|
+
|
|
443
|
+
.${PREFIX}-lockup { display: block; margin: 0 auto; color: var(--zrl-ink); }
|
|
444
|
+
|
|
445
|
+
.${PREFIX}-title {
|
|
446
|
+
margin: 18px 0 0;
|
|
447
|
+
font-size: 18px;
|
|
448
|
+
font-weight: 600;
|
|
449
|
+
letter-spacing: -0.01em;
|
|
450
|
+
line-height: 1.3;
|
|
451
|
+
color: var(--zrl-ink);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.${PREFIX}-body-text {
|
|
455
|
+
margin: 6px auto 0;
|
|
456
|
+
max-width: 30ch;
|
|
457
|
+
font-size: 14px;
|
|
458
|
+
line-height: 1.55;
|
|
459
|
+
color: var(--zrl-ink-soft);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.${PREFIX}-qr-well {
|
|
463
|
+
position: relative;
|
|
464
|
+
display: grid;
|
|
465
|
+
place-items: center;
|
|
466
|
+
box-sizing: border-box;
|
|
467
|
+
width: 204px;
|
|
468
|
+
height: 204px;
|
|
469
|
+
margin: 20px auto 0;
|
|
470
|
+
padding: 12px;
|
|
471
|
+
border: 1px solid var(--zrl-line);
|
|
472
|
+
border-radius: 16px;
|
|
473
|
+
background: var(--zrl-qr-bg);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.${PREFIX}-qr {
|
|
477
|
+
display: block;
|
|
478
|
+
width: 100%;
|
|
479
|
+
height: 100%;
|
|
480
|
+
border-radius: 8px;
|
|
481
|
+
transition: filter 300ms cubic-bezier(0.23, 1, 0.32, 1),
|
|
482
|
+
opacity 300ms cubic-bezier(0.23, 1, 0.32, 1),
|
|
483
|
+
transform 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/* Once the code is claimed the QR is spent. Blurring it out rather than
|
|
487
|
+
swapping it keeps one object on screen through the state change, so the eye
|
|
488
|
+
reads a transformation instead of two things trading places. */
|
|
489
|
+
.${PREFIX}-qr[data-spent="true"] { opacity: 0.2; filter: blur(3px); transform: scale(0.96); }
|
|
490
|
+
|
|
491
|
+
.${PREFIX}-qr-overlay {
|
|
492
|
+
position: absolute;
|
|
493
|
+
inset: 0;
|
|
494
|
+
display: grid;
|
|
495
|
+
place-items: center;
|
|
496
|
+
animation: ${PREFIX}-fade 200ms ease-out both;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.${PREFIX}-qr-badge {
|
|
500
|
+
display: grid;
|
|
501
|
+
place-items: center;
|
|
502
|
+
width: 56px;
|
|
503
|
+
height: 56px;
|
|
504
|
+
border-radius: 999px;
|
|
505
|
+
background: var(--zrl-accent-soft);
|
|
506
|
+
color: var(--zrl-accent-ink);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.${PREFIX}-status {
|
|
510
|
+
display: flex;
|
|
511
|
+
align-items: center;
|
|
512
|
+
justify-content: center;
|
|
513
|
+
gap: 8px;
|
|
514
|
+
margin-top: 20px;
|
|
515
|
+
font-size: 14px;
|
|
516
|
+
font-weight: 500;
|
|
517
|
+
color: var(--zrl-ink);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.${PREFIX}-dot { position: relative; display: grid; place-items: center; width: 8px; height: 8px; }
|
|
521
|
+
.${PREFIX}-dot i {
|
|
522
|
+
position: absolute;
|
|
523
|
+
width: 8px;
|
|
524
|
+
height: 8px;
|
|
525
|
+
border-radius: 999px;
|
|
526
|
+
background: var(--zrl-accent);
|
|
527
|
+
font-style: normal;
|
|
528
|
+
}
|
|
529
|
+
.${PREFIX}-dot i:first-child { animation: ${PREFIX}-ping 1.8s cubic-bezier(0.23, 1, 0.32, 1) infinite; }
|
|
530
|
+
|
|
531
|
+
.${PREFIX}-timer {
|
|
532
|
+
margin: 4px 0 0;
|
|
533
|
+
font-size: 12px;
|
|
534
|
+
font-variant-numeric: tabular-nums;
|
|
535
|
+
color: var(--zrl-ink-mute);
|
|
536
|
+
transition: color 200ms ease-out;
|
|
537
|
+
}
|
|
538
|
+
.${PREFIX}-timer[data-urgent="true"] { color: var(--zrl-urgent); }
|
|
539
|
+
|
|
540
|
+
.${PREFIX}-help {
|
|
541
|
+
padding: 14px 24px;
|
|
542
|
+
border-top: 1px solid var(--zrl-line-soft);
|
|
543
|
+
background: var(--zrl-surface-sunken);
|
|
544
|
+
border-radius: 0;
|
|
545
|
+
}
|
|
546
|
+
.${PREFIX}-help-title { margin: 0; font-size: 12px; font-weight: 600; color: var(--zrl-ink); }
|
|
547
|
+
.${PREFIX}-help-body {
|
|
548
|
+
margin: 4px auto 0;
|
|
549
|
+
max-width: 34ch;
|
|
550
|
+
font-size: 12px;
|
|
551
|
+
line-height: 1.55;
|
|
552
|
+
color: var(--zrl-ink-soft);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
.${PREFIX}-footer { padding: 12px; border-top: 1px solid var(--zrl-line-soft); }
|
|
556
|
+
|
|
557
|
+
.${PREFIX}-cancel {
|
|
558
|
+
display: block;
|
|
559
|
+
width: 100%;
|
|
560
|
+
padding: 10px;
|
|
561
|
+
border: 0;
|
|
562
|
+
border-radius: 12px;
|
|
563
|
+
background: transparent;
|
|
564
|
+
font: inherit;
|
|
565
|
+
font-size: 14px;
|
|
566
|
+
font-weight: 500;
|
|
567
|
+
color: var(--zrl-ink-soft);
|
|
568
|
+
cursor: pointer;
|
|
569
|
+
transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
|
|
570
|
+
}
|
|
571
|
+
.${PREFIX}-cancel:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
|
|
572
|
+
.${PREFIX}-cancel:active { transform: scale(0.99); }
|
|
573
|
+
|
|
574
|
+
.${PREFIX}-secured {
|
|
575
|
+
display: flex;
|
|
576
|
+
align-items: center;
|
|
577
|
+
justify-content: center;
|
|
578
|
+
gap: 6px;
|
|
579
|
+
margin: 6px 0 0;
|
|
580
|
+
font-size: 12px;
|
|
581
|
+
color: var(--zrl-ink-mute);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
.${PREFIX}-close {
|
|
585
|
+
position: absolute;
|
|
586
|
+
top: 12px;
|
|
587
|
+
inset-inline-end: 12px;
|
|
588
|
+
display: grid;
|
|
589
|
+
place-items: center;
|
|
590
|
+
width: 32px;
|
|
591
|
+
height: 32px;
|
|
592
|
+
padding: 0;
|
|
593
|
+
border: 0;
|
|
594
|
+
border-radius: 8px;
|
|
595
|
+
background: transparent;
|
|
596
|
+
color: var(--zrl-ink-mute);
|
|
597
|
+
cursor: pointer;
|
|
598
|
+
transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
|
|
599
|
+
}
|
|
600
|
+
.${PREFIX}-close:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
|
|
601
|
+
.${PREFIX}-close:active { transform: scale(0.95); }
|
|
602
|
+
|
|
603
|
+
.${PREFIX}-card :focus-visible {
|
|
604
|
+
outline: 2px solid var(--zrl-accent);
|
|
605
|
+
outline-offset: 2px;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
@keyframes ${PREFIX}-fade { from { opacity: 0 } to { opacity: 1 } }
|
|
609
|
+
@keyframes ${PREFIX}-rise {
|
|
610
|
+
from { opacity: 0; transform: translateY(10px) scale(0.98) }
|
|
611
|
+
to { opacity: 1; transform: none }
|
|
612
|
+
}
|
|
613
|
+
@keyframes ${PREFIX}-ping {
|
|
614
|
+
0% { transform: scale(1); opacity: 0.5 }
|
|
615
|
+
70%, 100% { transform: scale(2.6); opacity: 0 }
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
@media (prefers-reduced-motion: reduce) {
|
|
619
|
+
.${PREFIX}-scrim,
|
|
620
|
+
.${PREFIX}-card,
|
|
621
|
+
.${PREFIX}-qr-overlay { animation: none }
|
|
622
|
+
.${PREFIX}-dot i:first-child { animation: none; opacity: 0.35 }
|
|
623
|
+
.${PREFIX}-qr,
|
|
624
|
+
.${PREFIX}-cancel,
|
|
625
|
+
.${PREFIX}-close,
|
|
626
|
+
.${PREFIX}-timer { transition: none }
|
|
627
|
+
}
|
|
628
|
+
`;
|
|
629
|
+
function ensureStyles() {
|
|
630
|
+
if (typeof document === "undefined") return;
|
|
631
|
+
if (document.getElementById(STYLE_ELEMENT_ID)) return;
|
|
632
|
+
const el = document.createElement("style");
|
|
633
|
+
el.id = STYLE_ELEMENT_ID;
|
|
634
|
+
el.textContent = CSS;
|
|
635
|
+
document.head.appendChild(el);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// src/PairingModal.tsx
|
|
639
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
640
|
+
var DEFAULT_PAIRING_TIMEOUT_MS = 12e4;
|
|
641
|
+
var URGENT_SECONDS = 20;
|
|
642
|
+
function mmss(totalSeconds) {
|
|
643
|
+
const m = Math.floor(totalSeconds / 60);
|
|
644
|
+
const s = totalSeconds % 60;
|
|
645
|
+
return `${m}:${String(s).padStart(2, "0")}`;
|
|
646
|
+
}
|
|
647
|
+
var IconClose = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }) });
|
|
648
|
+
var IconPhone = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("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: [
|
|
649
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: "6", y: "2", width: "12", height: "20", rx: "2.5" }),
|
|
650
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M11 18.5h2" })
|
|
651
|
+
] });
|
|
652
|
+
var IconShield = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("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: [
|
|
653
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" }),
|
|
654
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m9 12 2 2 4-4" })
|
|
655
|
+
] });
|
|
656
|
+
function PairingModal({
|
|
657
|
+
state,
|
|
658
|
+
qrUrl,
|
|
659
|
+
onCancel,
|
|
660
|
+
locale,
|
|
661
|
+
theme = "auto",
|
|
662
|
+
timeoutMs = DEFAULT_PAIRING_TIMEOUT_MS
|
|
663
|
+
}) {
|
|
664
|
+
const t = strings(locale);
|
|
665
|
+
const titleId = (0, import_react.useId)();
|
|
666
|
+
const closeRef = (0, import_react.useRef)(null);
|
|
667
|
+
const deadlineRef = (0, import_react.useRef)(0);
|
|
668
|
+
const [remaining, setRemaining] = (0, import_react.useState)(Math.round(timeoutMs / 1e3));
|
|
669
|
+
const settled = state.status === "claimed" || state.status === "enrolling";
|
|
670
|
+
const onCancelRef = (0, import_react.useRef)(onCancel);
|
|
671
|
+
onCancelRef.current = onCancel;
|
|
672
|
+
(0, import_react.useEffect)(() => {
|
|
673
|
+
ensureStyles();
|
|
674
|
+
}, []);
|
|
675
|
+
(0, import_react.useEffect)(() => {
|
|
676
|
+
const serverMs = typeof state.expiresIn === "number" ? state.expiresIn * 1e3 : Infinity;
|
|
677
|
+
deadlineRef.current = Date.now() + Math.min(timeoutMs, serverMs);
|
|
678
|
+
setRemaining(Math.round(Math.min(timeoutMs, serverMs) / 1e3));
|
|
679
|
+
const id = setInterval(() => {
|
|
680
|
+
const left = Math.max(0, Math.ceil((deadlineRef.current - Date.now()) / 1e3));
|
|
681
|
+
setRemaining(left);
|
|
682
|
+
if (left === 0) {
|
|
683
|
+
clearInterval(id);
|
|
684
|
+
onCancelRef.current();
|
|
685
|
+
}
|
|
686
|
+
}, 1e3);
|
|
687
|
+
return () => clearInterval(id);
|
|
688
|
+
}, [timeoutMs]);
|
|
689
|
+
(0, import_react.useEffect)(() => {
|
|
690
|
+
const onKey = (e) => {
|
|
691
|
+
if (e.key === "Escape") onCancelRef.current();
|
|
692
|
+
};
|
|
693
|
+
document.addEventListener("keydown", onKey);
|
|
694
|
+
const previous = document.body.style.overflow;
|
|
695
|
+
document.body.style.overflow = "hidden";
|
|
696
|
+
closeRef.current?.focus();
|
|
697
|
+
return () => {
|
|
698
|
+
document.removeEventListener("keydown", onKey);
|
|
699
|
+
document.body.style.overflow = previous;
|
|
700
|
+
};
|
|
701
|
+
}, []);
|
|
702
|
+
if (typeof document === "undefined") return null;
|
|
703
|
+
const body = state.status === "enrolling" ? t.bodyEnrolling : settled ? t.bodyApprove : t.bodyScan;
|
|
704
|
+
return (0, import_react_dom.createPortal)(
|
|
705
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `${cx("root")} ${cx("scrim")}`, "data-theme": theme, onClick: onCancel, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
706
|
+
"div",
|
|
707
|
+
{
|
|
708
|
+
className: cx("card"),
|
|
709
|
+
role: "dialog",
|
|
710
|
+
"aria-modal": "true",
|
|
711
|
+
"aria-labelledby": titleId,
|
|
712
|
+
dir: isRtl(locale) ? "rtl" : "ltr",
|
|
713
|
+
onClick: (e) => e.stopPropagation(),
|
|
714
|
+
children: [
|
|
715
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { ref: closeRef, type: "button", className: cx("close"), "aria-label": t.close, onClick: onCancel, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconClose, {}) }),
|
|
716
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("body"), children: [
|
|
717
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ZorealLockup, { height: 44, className: cx("lockup") }),
|
|
718
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { id: titleId, className: cx("title"), children: settled ? t.titleApprove : t.title }),
|
|
719
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("body-text"), children: body }),
|
|
720
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("qr-well"), children: [
|
|
721
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { className: cx("qr"), "data-spent": settled, src: qrUrl, alt: t.qrAlt, width: 180, height: 180 }),
|
|
722
|
+
settled && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cx("qr-overlay"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cx("qr-badge"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconPhone, {}) }) })
|
|
723
|
+
] }),
|
|
724
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("status"), children: [
|
|
725
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: cx("dot"), children: [
|
|
726
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", {}),
|
|
727
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("i", {})
|
|
728
|
+
] }),
|
|
729
|
+
settled ? t.waitingApproval : t.waiting
|
|
730
|
+
] }),
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("timer"), "data-urgent": remaining <= URGENT_SECONDS, children: interpolate(t.expiresIn, mmss(remaining)) })
|
|
732
|
+
] }),
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("help"), children: [
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("help-title"), children: t.noIdTitle }),
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: cx("help-body"), children: t.noIdBody })
|
|
736
|
+
] }),
|
|
737
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cx("footer"), children: [
|
|
738
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: cx("cancel"), onClick: onCancel, children: t.cancel }),
|
|
739
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: cx("secured"), children: [
|
|
740
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IconShield, {}),
|
|
741
|
+
t.secured
|
|
742
|
+
] })
|
|
743
|
+
] })
|
|
744
|
+
]
|
|
745
|
+
}
|
|
746
|
+
) }),
|
|
747
|
+
document.body
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// src/context.tsx
|
|
752
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
753
|
+
var ZorealOAuthContext = (0, import_react2.createContext)(null);
|
|
754
|
+
var PairingHostContext = (0, import_react2.createContext)(null);
|
|
755
|
+
function useZorealPairingHost() {
|
|
756
|
+
return (0, import_react2.useContext)(PairingHostContext);
|
|
757
|
+
}
|
|
48
758
|
function ZorealOAuthProvider({
|
|
49
759
|
clientId,
|
|
50
760
|
issuer = DEFAULT_ISSUER,
|
|
51
761
|
locale,
|
|
762
|
+
theme = "auto",
|
|
763
|
+
pairingUI = "modal",
|
|
764
|
+
pairingTimeoutMs,
|
|
52
765
|
children
|
|
53
766
|
}) {
|
|
54
|
-
const
|
|
767
|
+
const [pairing, setPairing] = (0, import_react2.useState)(null);
|
|
768
|
+
const value = (0, import_react2.useMemo)(
|
|
55
769
|
() => ({ clientId, issuer: issuer.replace(/\/$/, ""), locale }),
|
|
56
770
|
[clientId, issuer, locale]
|
|
57
771
|
);
|
|
58
|
-
|
|
772
|
+
const host = pairingUI === "modal" ? setPairing : null;
|
|
773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ZorealOAuthContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PairingHostContext.Provider, { value: host, children: [
|
|
774
|
+
children,
|
|
775
|
+
pairing && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
776
|
+
PairingModal,
|
|
777
|
+
{
|
|
778
|
+
state: pairing.state,
|
|
779
|
+
qrUrl: pairing.qrUrl,
|
|
780
|
+
onCancel: pairing.cancel,
|
|
781
|
+
locale,
|
|
782
|
+
theme,
|
|
783
|
+
timeoutMs: pairingTimeoutMs
|
|
784
|
+
}
|
|
785
|
+
)
|
|
786
|
+
] }) });
|
|
59
787
|
}
|
|
60
788
|
function useZorealOAuth() {
|
|
61
|
-
const ctx = (0,
|
|
789
|
+
const ctx = (0, import_react2.useContext)(ZorealOAuthContext);
|
|
62
790
|
if (!ctx) {
|
|
63
791
|
throw new Error(
|
|
64
792
|
"useZorealOAuth must be used inside <ZorealOAuthProvider clientId=...>. Wrap your app (or the part that logs in) in the provider."
|
|
@@ -68,10 +796,10 @@ function useZorealOAuth() {
|
|
|
68
796
|
}
|
|
69
797
|
|
|
70
798
|
// src/ZorealLogin.tsx
|
|
71
|
-
var
|
|
799
|
+
var import_react4 = require("react");
|
|
72
800
|
|
|
73
801
|
// src/useZorealLogin.ts
|
|
74
|
-
var
|
|
802
|
+
var import_react3 = require("react");
|
|
75
803
|
|
|
76
804
|
// src/jwt.ts
|
|
77
805
|
function unsafeClaims(idToken) {
|
|
@@ -225,12 +953,21 @@ function generateState() {
|
|
|
225
953
|
// src/useZorealLogin.ts
|
|
226
954
|
function useZorealFlow(options) {
|
|
227
955
|
const { clientId, issuer, locale } = useZorealOAuth();
|
|
228
|
-
const [pairing, setPairing] = (0,
|
|
229
|
-
const
|
|
230
|
-
const
|
|
956
|
+
const [pairing, setPairing] = (0, import_react3.useState)(null);
|
|
957
|
+
const publish = useZorealPairingHost();
|
|
958
|
+
const publishRef = (0, import_react3.useRef)(publish);
|
|
959
|
+
publishRef.current = publish;
|
|
960
|
+
const abortRef = (0, import_react3.useRef)(null);
|
|
961
|
+
const optionsRef = (0, import_react3.useRef)(options);
|
|
231
962
|
optionsRef.current = options;
|
|
232
|
-
(0,
|
|
233
|
-
|
|
963
|
+
(0, import_react3.useEffect)(
|
|
964
|
+
() => () => {
|
|
965
|
+
abortRef.current?.abort();
|
|
966
|
+
publishRef.current?.(null);
|
|
967
|
+
},
|
|
968
|
+
[]
|
|
969
|
+
);
|
|
970
|
+
const login = (0, import_react3.useCallback)(() => {
|
|
234
971
|
const opts = optionsRef.current;
|
|
235
972
|
const run = async () => {
|
|
236
973
|
abortRef.current?.abort();
|
|
@@ -264,6 +1001,7 @@ function useZorealFlow(options) {
|
|
|
264
1001
|
const cancel = () => {
|
|
265
1002
|
controller.abort();
|
|
266
1003
|
setPairing(null);
|
|
1004
|
+
publishRef.current?.(null);
|
|
267
1005
|
};
|
|
268
1006
|
const surface = {
|
|
269
1007
|
pairUrl: started.pair_url,
|
|
@@ -280,6 +1018,9 @@ function useZorealFlow(options) {
|
|
|
280
1018
|
cancel
|
|
281
1019
|
};
|
|
282
1020
|
setPairing(active);
|
|
1021
|
+
if (!useAppLink) {
|
|
1022
|
+
publishRef.current?.({ state: active.state, qrUrl: surface.qrUrl, cancel });
|
|
1023
|
+
}
|
|
283
1024
|
opts.onPairingStateChange?.(active.state);
|
|
284
1025
|
if (useAppLink) {
|
|
285
1026
|
window.location.assign(started.pair_url);
|
|
@@ -292,12 +1033,16 @@ function useZorealFlow(options) {
|
|
|
292
1033
|
setPairing(
|
|
293
1034
|
(p) => p && p.requestId === started.request_id ? { ...p, state: enriched } : p
|
|
294
1035
|
);
|
|
1036
|
+
if (!useAppLink) {
|
|
1037
|
+
publishRef.current?.({ state: enriched, qrUrl: surface.qrUrl, cancel });
|
|
1038
|
+
}
|
|
295
1039
|
opts.onPairingStateChange?.(enriched);
|
|
296
1040
|
},
|
|
297
1041
|
controller.signal
|
|
298
1042
|
);
|
|
299
1043
|
}
|
|
300
1044
|
setPairing(null);
|
|
1045
|
+
publishRef.current?.(null);
|
|
301
1046
|
if (flow === "auth-code") {
|
|
302
1047
|
opts.onCode?.({
|
|
303
1048
|
code,
|
|
@@ -323,6 +1068,7 @@ function useZorealFlow(options) {
|
|
|
323
1068
|
opts.onCredential?.(response);
|
|
324
1069
|
} catch (e) {
|
|
325
1070
|
setPairing(null);
|
|
1071
|
+
publishRef.current?.(null);
|
|
326
1072
|
if (e instanceof DOMException && e.name === "AbortError") return;
|
|
327
1073
|
if (e instanceof FlowAbandonedError) {
|
|
328
1074
|
opts.onNonOAuthError?.(e.reason);
|
|
@@ -358,7 +1104,7 @@ function useZorealLogin(options) {
|
|
|
358
1104
|
}
|
|
359
1105
|
|
|
360
1106
|
// src/ZorealLogin.tsx
|
|
361
|
-
var
|
|
1107
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
362
1108
|
var TEXTS = {
|
|
363
1109
|
continue_with: "Continue with ZOREAL",
|
|
364
1110
|
signin_with: "Sign in with ZOREAL",
|
|
@@ -370,80 +1116,6 @@ var SIZES = {
|
|
|
370
1116
|
medium: { height: 38, font: 14, pad: 16 },
|
|
371
1117
|
small: { height: 32, font: 12, pad: 12 }
|
|
372
1118
|
};
|
|
373
|
-
var Mark = ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
374
|
-
"svg",
|
|
375
|
-
{
|
|
376
|
-
width: size,
|
|
377
|
-
height: size,
|
|
378
|
-
viewBox: "8.4 7.4 62.2 62.2",
|
|
379
|
-
fill: "currentColor",
|
|
380
|
-
fillRule: "evenodd",
|
|
381
|
-
"aria-hidden": true,
|
|
382
|
-
focusable: "false",
|
|
383
|
-
children: [
|
|
384
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.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" }),
|
|
385
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.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" }),
|
|
386
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.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" }),
|
|
387
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.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" }),
|
|
388
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.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" }),
|
|
389
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.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" }),
|
|
390
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.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" })
|
|
391
|
-
]
|
|
392
|
-
}
|
|
393
|
-
);
|
|
394
|
-
var PairingPanel = ({ pairing }) => {
|
|
395
|
-
const { status } = pairing.state;
|
|
396
|
-
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.";
|
|
397
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
398
|
-
"div",
|
|
399
|
-
{
|
|
400
|
-
role: "dialog",
|
|
401
|
-
"aria-label": "Log in with ZOREAL",
|
|
402
|
-
style: {
|
|
403
|
-
marginTop: 8,
|
|
404
|
-
padding: 16,
|
|
405
|
-
width: 232,
|
|
406
|
-
borderRadius: 12,
|
|
407
|
-
border: "1px solid rgba(128,128,128,0.35)",
|
|
408
|
-
background: "Canvas",
|
|
409
|
-
color: "CanvasText",
|
|
410
|
-
textAlign: "center",
|
|
411
|
-
fontFamily: "inherit"
|
|
412
|
-
},
|
|
413
|
-
children: [
|
|
414
|
-
!pairing.appLink && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
415
|
-
"img",
|
|
416
|
-
{
|
|
417
|
-
src: pairing.qrUrl,
|
|
418
|
-
alt: `QR code for ${pairing.pairUrl}`,
|
|
419
|
-
width: 200,
|
|
420
|
-
height: 200,
|
|
421
|
-
style: { display: "block", margin: "0 auto", borderRadius: 8 }
|
|
422
|
-
}
|
|
423
|
-
),
|
|
424
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { margin: "10px 0 0", fontSize: 12, lineHeight: 1.5 }, children: line }),
|
|
425
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
426
|
-
"button",
|
|
427
|
-
{
|
|
428
|
-
type: "button",
|
|
429
|
-
onClick: pairing.cancel,
|
|
430
|
-
style: {
|
|
431
|
-
marginTop: 10,
|
|
432
|
-
border: "none",
|
|
433
|
-
background: "none",
|
|
434
|
-
color: "inherit",
|
|
435
|
-
opacity: 0.6,
|
|
436
|
-
fontSize: 12,
|
|
437
|
-
cursor: "pointer",
|
|
438
|
-
textDecoration: "underline"
|
|
439
|
-
},
|
|
440
|
-
children: "Cancel"
|
|
441
|
-
}
|
|
442
|
-
)
|
|
443
|
-
]
|
|
444
|
-
}
|
|
445
|
-
);
|
|
446
|
-
};
|
|
447
1119
|
function ZorealLogin(props) {
|
|
448
1120
|
const {
|
|
449
1121
|
onSuccess,
|
|
@@ -459,7 +1131,7 @@ function ZorealLogin(props) {
|
|
|
459
1131
|
click_listener,
|
|
460
1132
|
...request
|
|
461
1133
|
} = props;
|
|
462
|
-
const { login
|
|
1134
|
+
const { login } = useZorealFlow({
|
|
463
1135
|
...request,
|
|
464
1136
|
flow: "browser-direct",
|
|
465
1137
|
onCredential: onSuccess,
|
|
@@ -467,7 +1139,7 @@ function ZorealLogin(props) {
|
|
|
467
1139
|
onNonOAuthError: (e) => onError?.(e)
|
|
468
1140
|
});
|
|
469
1141
|
const s = SIZES[size];
|
|
470
|
-
const style = (0,
|
|
1142
|
+
const style = (0, import_react4.useMemo)(
|
|
471
1143
|
() => ({
|
|
472
1144
|
display: "inline-flex",
|
|
473
1145
|
alignItems: "center",
|
|
@@ -485,28 +1157,25 @@ function ZorealLogin(props) {
|
|
|
485
1157
|
}),
|
|
486
1158
|
[logo_alignment, s, shape, theme, width]
|
|
487
1159
|
);
|
|
488
|
-
return /* @__PURE__ */ (0,
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
),
|
|
504
|
-
internals.pairing && !internals.pairing.appLink && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PairingPanel, { pairing: internals.pairing })
|
|
505
|
-
] });
|
|
1160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ...containerProps, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1161
|
+
"button",
|
|
1162
|
+
{
|
|
1163
|
+
type: "button",
|
|
1164
|
+
style,
|
|
1165
|
+
onClick: () => {
|
|
1166
|
+
click_listener?.();
|
|
1167
|
+
login();
|
|
1168
|
+
},
|
|
1169
|
+
children: [
|
|
1170
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ZorealMark, { size: Math.round(s.font * 1.25) }),
|
|
1171
|
+
type === "standard" && TEXTS[text]
|
|
1172
|
+
]
|
|
1173
|
+
}
|
|
1174
|
+
) });
|
|
506
1175
|
}
|
|
507
1176
|
|
|
508
1177
|
// src/useZorealAutoLogin.ts
|
|
509
|
-
var
|
|
1178
|
+
var import_react5 = require("react");
|
|
510
1179
|
function useZorealAutoLogin(options) {
|
|
511
1180
|
const { login } = useZorealFlow({
|
|
512
1181
|
flow: "browser-direct",
|
|
@@ -523,8 +1192,8 @@ function useZorealAutoLogin(options) {
|
|
|
523
1192
|
},
|
|
524
1193
|
onNonOAuthError: (e) => options.onError?.(e)
|
|
525
1194
|
});
|
|
526
|
-
const fired = (0,
|
|
527
|
-
(0,
|
|
1195
|
+
const fired = (0, import_react5.useRef)(false);
|
|
1196
|
+
(0, import_react5.useEffect)(() => {
|
|
528
1197
|
if (options.disabled || fired.current) return;
|
|
529
1198
|
fired.current = true;
|
|
530
1199
|
login();
|
|
@@ -546,6 +1215,8 @@ function hasGrantedAnyScopeZoreal(response, firstScope, ...restScopes) {
|
|
|
546
1215
|
}
|
|
547
1216
|
// Annotate the CommonJS export names for ESM import in node:
|
|
548
1217
|
0 && (module.exports = {
|
|
1218
|
+
DEFAULT_PAIRING_TIMEOUT_MS,
|
|
1219
|
+
PairingModal,
|
|
549
1220
|
ZorealLogin,
|
|
550
1221
|
ZorealOAuthProvider,
|
|
551
1222
|
hasGrantedAllScopesZoreal,
|