qumra-pos-auth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,566 @@
1
+ import { b64url, NoblePinHasher, NobleSignatureVerifier } from './chunk-SRPTNNYT.js';
2
+
3
+ // src/errors.ts
4
+ var AuthNetworkError = class extends Error {
5
+ constructor(message, cause) {
6
+ super(message, { cause });
7
+ this.name = "AuthNetworkError";
8
+ }
9
+ };
10
+ var AuthRejectedError = class extends Error {
11
+ /** كود السيرفر لو متاح (invalid_grant, invalid_credentials …). */
12
+ code;
13
+ constructor(message, code, cause) {
14
+ super(message, { cause });
15
+ this.name = "AuthRejectedError";
16
+ this.code = code;
17
+ }
18
+ };
19
+
20
+ // src/time.ts
21
+ var systemClock = () => Date.now();
22
+ var SECOND = 1e3;
23
+ var MINUTE = 60 * SECOND;
24
+ var HOUR = 60 * MINUTE;
25
+ var DAY = 24 * HOUR;
26
+
27
+ // src/token/TokenManager.ts
28
+ var TokenManager = class {
29
+ vault;
30
+ api;
31
+ now;
32
+ skewMs;
33
+ onServerContact;
34
+ /** single-flight: كل النداءات المتزامنة بتشارك نفس عملية الـ refresh. */
35
+ inflight = null;
36
+ /**
37
+ * نسخة في الذاكرة من آخر توكنات معروفة. الغرض الوحيد: peekValidToken المتزامن
38
+ * — لأن SyncEngine.getAuthToken متزامن بينما الـ vault async. بتتحدّث مع كل
39
+ * تحميل/حفظ للتوكنات، ودورة الـ refresh الخلفية بتحافظ عليها دافية.
40
+ */
41
+ cached = null;
42
+ constructor(opts) {
43
+ this.vault = opts.vault;
44
+ this.api = opts.api;
45
+ this.now = opts.now ?? systemClock;
46
+ this.skewMs = opts.skewMs ?? 30 * SECOND;
47
+ this.onServerContact = opts.onServerContact;
48
+ }
49
+ /** تسجيل دخول أونلاين. بيرمي AuthRejectedError/AuthNetworkError زي الـ api. */
50
+ async login(input) {
51
+ const resp = await this.api.login(input);
52
+ const tokens = this.toTokens(resp);
53
+ await this.vault.saveTokens(tokens);
54
+ this.cached = tokens;
55
+ await this.onServerContact?.(this.now());
56
+ return tokens;
57
+ }
58
+ /** خروج: إبطال best-effort على السيرفر ثم مسح التوكنات المحلية. */
59
+ async logout() {
60
+ const tokens = await this.vault.loadTokens();
61
+ if (tokens && this.api.revoke) {
62
+ try {
63
+ await this.api.revoke(tokens.refreshToken);
64
+ } catch {
65
+ }
66
+ }
67
+ await this.vault.saveTokens(null);
68
+ this.cached = null;
69
+ }
70
+ async getTokens() {
71
+ const tokens = await this.vault.loadTokens();
72
+ this.cached = tokens;
73
+ return tokens;
74
+ }
75
+ /** يملأ الكاش من الـ vault مرة (عند الإقلاع) — علشان peek يشتغل قبل أي نداء. */
76
+ async primeCache() {
77
+ this.cached = await this.vault.loadTokens();
78
+ }
79
+ /**
80
+ * توكن access صالح متزامن من الكاش — من غير أي I/O أو refresh. ده اللي بيتوصّل
81
+ * لـ SyncEngine.getAuthToken. بيرجّع null لو مفيش كاش أو الكاش منتهي؛ دورة الـ
82
+ * refresh الخلفية (getValidToken) هي اللي بتجدّد الكاش.
83
+ */
84
+ peekValidToken() {
85
+ if (!this.cached) return null;
86
+ return this.isAccessValid(this.cached) ? this.cached.accessToken : null;
87
+ }
88
+ /**
89
+ * التوكن الصالح للـ SyncEngine. مابيرميش: أي فشل → null (= pause).
90
+ */
91
+ async getValidToken() {
92
+ const outcome = await this.ensureFresh();
93
+ switch (outcome.status) {
94
+ case "valid":
95
+ case "refreshed":
96
+ return outcome.tokens.accessToken;
97
+ default:
98
+ return null;
99
+ }
100
+ }
101
+ /**
102
+ * يضمن توكن access صالح: يرجّعه لو صالح، أو يعمل refresh دوّار single-flight.
103
+ * مابيرميش — بيرجّع RefreshOutcome. AuthService بيستخدمه لتحديث حالة الوصول.
104
+ */
105
+ async ensureFresh() {
106
+ const tokens = await this.vault.loadTokens();
107
+ this.cached = tokens;
108
+ if (!tokens) return { status: "signed-out" };
109
+ if (this.isAccessValid(tokens)) return { status: "valid", tokens };
110
+ if (!this.isRefreshValid(tokens)) return { status: "network" };
111
+ return this.refreshOnce();
112
+ }
113
+ isAccessValid(tokens) {
114
+ return this.now() < tokens.accessExpiresAt - this.skewMs;
115
+ }
116
+ isRefreshValid(tokens) {
117
+ return this.now() < tokens.refreshExpiresAt;
118
+ }
119
+ /** refresh single-flight: نداء واحد بس بيطير حتى لو اتنادى من كذا مكان. */
120
+ refreshOnce() {
121
+ if (this.inflight) return this.inflight;
122
+ this.inflight = this.doRefresh().finally(() => {
123
+ this.inflight = null;
124
+ });
125
+ return this.inflight;
126
+ }
127
+ async doRefresh() {
128
+ const current = await this.vault.loadTokens();
129
+ if (!current) return { status: "signed-out" };
130
+ if (this.isAccessValid(current)) return { status: "valid", tokens: current };
131
+ try {
132
+ const resp = await this.api.refresh(current.refreshToken);
133
+ const next = this.toTokens(resp);
134
+ await this.vault.saveTokens(next);
135
+ this.cached = next;
136
+ await this.onServerContact?.(this.now());
137
+ return { status: "refreshed", tokens: next };
138
+ } catch (err) {
139
+ if (err instanceof AuthRejectedError) {
140
+ await this.vault.saveTokens(null);
141
+ this.cached = null;
142
+ return { status: "rejected" };
143
+ }
144
+ if (err instanceof AuthNetworkError) {
145
+ return { status: "network" };
146
+ }
147
+ return { status: "network" };
148
+ }
149
+ }
150
+ toTokens(resp) {
151
+ const at = this.now();
152
+ return {
153
+ accessToken: resp.accessToken,
154
+ refreshToken: resp.refreshToken,
155
+ accessExpiresAt: at + resp.expiresInSec * SECOND,
156
+ refreshExpiresAt: at + resp.refreshExpiresInSec * SECOND,
157
+ tokenType: resp.tokenType ?? "Bearer"
158
+ };
159
+ }
160
+ };
161
+
162
+ // src/pin/PinManager.ts
163
+ var PinManager = class {
164
+ directory;
165
+ hasher;
166
+ now;
167
+ maxAttempts;
168
+ lockoutMs;
169
+ attempts = /* @__PURE__ */ new Map();
170
+ constructor(opts) {
171
+ this.directory = opts.directory;
172
+ this.hasher = opts.hasher;
173
+ this.now = opts.now ?? systemClock;
174
+ this.maxAttempts = opts.maxAttempts ?? 5;
175
+ this.lockoutMs = opts.lockoutMs ?? MINUTE;
176
+ }
177
+ /** قائمة الكاشيرية للعرض (من غير الـ hashes). */
178
+ async listCashiers() {
179
+ const rows = await this.directory.listCashiers();
180
+ return rows.map((c) => ({ id: c.id, name: c.name, active: c.active }));
181
+ }
182
+ /**
183
+ * يتحقق من PIN كاشير معيّن. النجاح بيصفّر عدّاد محاولاته؛ الفشل بيزوّده ويقفل
184
+ * مؤقتاً عند الوصول للحد.
185
+ */
186
+ async verify(cashierId, pin) {
187
+ const now = this.now();
188
+ const state = this.attempts.get(cashierId);
189
+ if (state && state.lockedUntil > now) {
190
+ return {
191
+ ok: false,
192
+ reason: "locked",
193
+ retryAfterMs: state.lockedUntil - now
194
+ };
195
+ }
196
+ const cashier = await this.findCashier(cashierId);
197
+ if (!cashier) return { ok: false, reason: "unknown-cashier" };
198
+ if (!cashier.active) return { ok: false, reason: "inactive" };
199
+ const valid = await this.hasher.verify(pin, cashier.pinHash);
200
+ if (valid) {
201
+ this.attempts.delete(cashierId);
202
+ return {
203
+ ok: true,
204
+ cashier: { cashierId: cashier.id, name: cashier.name, since: now }
205
+ };
206
+ }
207
+ return this.registerFailure(cashierId, now);
208
+ }
209
+ /** يفكّ القفل يدوياً (مثلاً المدير سمح). */
210
+ reset(cashierId) {
211
+ this.attempts.delete(cashierId);
212
+ }
213
+ registerFailure(cashierId, now) {
214
+ const prev = this.attempts.get(cashierId);
215
+ const count = (prev?.count ?? 0) + 1;
216
+ if (count >= this.maxAttempts) {
217
+ const lockedUntil = now + this.lockoutMs;
218
+ this.attempts.set(cashierId, { count: 0, lockedUntil });
219
+ return { ok: false, reason: "locked", retryAfterMs: this.lockoutMs };
220
+ }
221
+ this.attempts.set(cashierId, { count, lockedUntil: 0 });
222
+ return {
223
+ ok: false,
224
+ reason: "bad-pin",
225
+ attemptsLeft: this.maxAttempts - count
226
+ };
227
+ }
228
+ async findCashier(id) {
229
+ const rows = await this.directory.listCashiers();
230
+ return rows.find((c) => c.id === id);
231
+ }
232
+ };
233
+
234
+ // src/activation/ActivationManager.ts
235
+ var ActivationManager = class {
236
+ vault;
237
+ verifier;
238
+ publicKey;
239
+ now;
240
+ deviceId;
241
+ constructor(opts) {
242
+ this.vault = opts.vault;
243
+ this.verifier = opts.verifier;
244
+ this.publicKey = opts.publicKey;
245
+ this.now = opts.now ?? systemClock;
246
+ this.deviceId = opts.deviceId;
247
+ }
248
+ /**
249
+ * يتحقق من مفتاح تفعيل ويخزّنه لو صالح. الترتيب: صيغة → توقيع → الجهاز → الانتهاء.
250
+ * التوقيع بيتفحص قبل أي حاجة تانية علشان مانثقش في أي claim قبل التأكد إنه من قمرة.
251
+ */
252
+ async activate(activationKey) {
253
+ const parsed = this.parse(activationKey);
254
+ if (!parsed) return { ok: false, reason: "malformed" };
255
+ const okSig = await this.verifier.verify(
256
+ parsed.signedBytes,
257
+ parsed.signature,
258
+ this.publicKey
259
+ );
260
+ if (!okSig) return { ok: false, reason: "bad-signature" };
261
+ const claims = parsed.claims;
262
+ if (this.deviceId !== void 0 && claims.deviceId !== this.deviceId) {
263
+ return { ok: false, reason: "wrong-device" };
264
+ }
265
+ const now = this.now();
266
+ const graceMs = claims.graceMs ?? 0;
267
+ if (now >= claims.expiresAt + graceMs) {
268
+ return { ok: false, reason: "expired" };
269
+ }
270
+ const stored = {
271
+ claims,
272
+ key: activationKey,
273
+ verifiedAt: now
274
+ };
275
+ await this.vault.saveActivation(stored);
276
+ return { ok: true, claims };
277
+ }
278
+ async getActivation() {
279
+ return this.vault.loadActivation();
280
+ }
281
+ /**
282
+ * يعيد التحقق من المفتاح المخزّن (توقيع + جهاز) ويحدّث verifiedAt. بيُستدعى عند
283
+ * الإقلاع علشان نتأكد إن المفتاح المخزّن لسه سليم ومش متلاعب فيه.
284
+ */
285
+ async revalidateStored() {
286
+ const stored = await this.vault.loadActivation();
287
+ if (!stored) return null;
288
+ return this.activate(stored.key);
289
+ }
290
+ async clear() {
291
+ await this.vault.saveActivation(null);
292
+ }
293
+ parse(key) {
294
+ const dot = key.indexOf(".");
295
+ if (dot <= 0 || dot === key.length - 1) return null;
296
+ const payloadB64 = key.slice(0, dot);
297
+ const sigB64 = key.slice(dot + 1);
298
+ let claims;
299
+ let signature;
300
+ try {
301
+ const json = new TextDecoder().decode(b64url.decode(payloadB64));
302
+ claims = JSON.parse(json);
303
+ signature = b64url.decode(sigB64);
304
+ } catch {
305
+ return null;
306
+ }
307
+ if (!isValidClaims(claims)) return null;
308
+ const signedBytes = new TextEncoder().encode(payloadB64);
309
+ return { claims, signedBytes, signature };
310
+ }
311
+ };
312
+ function isValidClaims(c) {
313
+ if (typeof c !== "object" || c === null) return false;
314
+ const o = c;
315
+ return typeof o.merchantId === "string" && typeof o.deviceId === "string" && typeof o.issuedAt === "number" && typeof o.expiresAt === "number";
316
+ }
317
+
318
+ // src/policy.ts
319
+ var DEFAULT_ACCESS_POLICY = {
320
+ maxOfflineMs: 30 * DAY,
321
+ graceMs: 3 * DAY
322
+ };
323
+
324
+ // src/service/AuthService.ts
325
+ var EMPTY_META = {
326
+ lastServerContactAt: null,
327
+ activatedOnlineAt: null
328
+ };
329
+ var AuthService = class {
330
+ vault;
331
+ now;
332
+ policy;
333
+ tokens;
334
+ pins;
335
+ activation;
336
+ listeners = /* @__PURE__ */ new Set();
337
+ status = {
338
+ mode: "unactivated",
339
+ access: "locked",
340
+ tokenValid: false,
341
+ cashier: null,
342
+ graceEndsAt: null,
343
+ lockedReason: LOCK_REASON_UNACTIVATED,
344
+ lastServerContactAt: null,
345
+ activation: null
346
+ };
347
+ constructor(opts) {
348
+ this.vault = opts.vault;
349
+ this.tokens = opts.tokenManager;
350
+ this.pins = opts.pinManager;
351
+ this.activation = opts.activationManager;
352
+ this.policy = opts.policy ?? DEFAULT_ACCESS_POLICY;
353
+ this.now = opts.now ?? systemClock;
354
+ }
355
+ // -------------------------------------------------------------------------
356
+ // إقلاع + إعادة تقييم
357
+ // -------------------------------------------------------------------------
358
+ /** الإقلاع: يملأ كاش التوكن، يعيد التحقق من مفتاح التفعيل المخزّن، ثم يحسب الحالة. */
359
+ async init() {
360
+ await this.tokens.primeCache();
361
+ const check = await this.activation.revalidateStored();
362
+ if (check && !check.ok && (check.reason === "bad-signature" || check.reason === "wrong-device")) {
363
+ await this.activation.clear();
364
+ }
365
+ return this.reevaluate();
366
+ }
367
+ /**
368
+ * يحاول تحديث التوكن (لو النت رجع) ثم يعيد حساب الحالة. التطبيق بينادي ده دورياً
369
+ * وبعد أي reconnect. مابيرميش.
370
+ */
371
+ async refresh() {
372
+ await this.tokens.ensureFresh();
373
+ return this.reevaluate();
374
+ }
375
+ getStatus() {
376
+ return this.status;
377
+ }
378
+ /** هل مسموح ببيع جديد دلوقتي؟ (locked = لأ). */
379
+ canSell() {
380
+ return this.status.access !== "locked";
381
+ }
382
+ onStatusChange(cb) {
383
+ this.listeners.add(cb);
384
+ cb(this.status);
385
+ return () => this.listeners.delete(cb);
386
+ }
387
+ // -------------------------------------------------------------------------
388
+ // الجهاز/التاجر
389
+ // -------------------------------------------------------------------------
390
+ /** تسجيل دخول أونلاين. بيرمي زي الـ api (rejected/network). */
391
+ async onlineLogin(input) {
392
+ await this.tokens.login(input);
393
+ return this.reevaluate();
394
+ }
395
+ /** إدخال مفتاح تفعيل أوفلاين. */
396
+ async activateOffline(activationKey) {
397
+ const result = await this.activation.activate(activationKey);
398
+ await this.reevaluate();
399
+ return result;
400
+ }
401
+ /** خروج التاجر: يمسح التوكنات وجلسة الكاشير (مش البيانات، مش التفعيل). */
402
+ async logout() {
403
+ await this.tokens.logout();
404
+ await this.vault.saveSession(null);
405
+ return this.reevaluate();
406
+ }
407
+ /** callback الوحيد للـ SyncEngine (async). null = pause. */
408
+ getValidToken() {
409
+ return this.tokens.getValidToken();
410
+ }
411
+ /**
412
+ * نسخة متزامنة للـ SyncEngine (getAuthToken بتاعه متزامن). بترجّع آخر توكن صالح
413
+ * من الكاش من غير I/O؛ refresh()/getValidToken الدورية هي اللي بتدفّي الكاش.
414
+ */
415
+ getAccessTokenSync() {
416
+ return this.tokens.peekValidToken();
417
+ }
418
+ /** يُمرَّر للـ TokenManager: يسجّل آخر اتصال ناجح بالسيرفر ويعلّم التفعيل الأونلاين. */
419
+ async recordServerContact(at) {
420
+ const meta = await this.vault.loadMeta() ?? EMPTY_META;
421
+ await this.vault.saveMeta({
422
+ lastServerContactAt: at,
423
+ activatedOnlineAt: meta.activatedOnlineAt ?? at
424
+ });
425
+ }
426
+ // -------------------------------------------------------------------------
427
+ // الكاشير (PIN)
428
+ // -------------------------------------------------------------------------
429
+ async listCashiers() {
430
+ return this.pins.listCashiers();
431
+ }
432
+ async cashierLogin(cashierId, pin) {
433
+ const result = await this.pins.verify(cashierId, pin);
434
+ if (result.ok) {
435
+ await this.vault.saveSession(result.cashier);
436
+ await this.reevaluate();
437
+ }
438
+ return result;
439
+ }
440
+ async cashierLogout() {
441
+ await this.vault.saveSession(null);
442
+ await this.reevaluate();
443
+ }
444
+ // -------------------------------------------------------------------------
445
+ // حساب الحالة
446
+ // -------------------------------------------------------------------------
447
+ async reevaluate() {
448
+ const next = await this.computeStatus();
449
+ const changed = JSON.stringify(next) !== JSON.stringify(this.status);
450
+ this.status = next;
451
+ if (changed) {
452
+ for (const cb of this.listeners) cb(next);
453
+ }
454
+ return next;
455
+ }
456
+ async computeStatus() {
457
+ const [tokens, session, activation, metaRaw] = await Promise.all([
458
+ this.vault.loadTokens(),
459
+ this.vault.loadSession(),
460
+ this.vault.loadActivation(),
461
+ this.vault.loadMeta()
462
+ ]);
463
+ const meta = metaRaw ?? EMPTY_META;
464
+ const now = this.now();
465
+ const tokenValid = tokens ? this.tokens.isAccessValid(tokens) : false;
466
+ const mode = deriveMode(tokenValid, meta, activation);
467
+ const access = computeAccess(mode, now, meta, activation, this.policy);
468
+ return {
469
+ mode,
470
+ access: access.state,
471
+ tokenValid,
472
+ cashier: session,
473
+ graceEndsAt: access.graceEndsAt,
474
+ lockedReason: access.lockedReason,
475
+ lastServerContactAt: meta.lastServerContactAt,
476
+ activation
477
+ };
478
+ }
479
+ };
480
+ var LOCK_REASON_UNACTIVATED = "\u0627\u0644\u062C\u0647\u0627\u0632 \u063A\u064A\u0631 \u0645\u0641\u0639\u0651\u0644 \u2014 \u0633\u062C\u0651\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0623\u0648\u0646\u0644\u0627\u064A\u0646 \u0623\u0648 \u0623\u062F\u062E\u0644 \u0645\u0641\u062A\u0627\u062D \u062A\u0641\u0639\u064A\u0644";
481
+ var LOCK_REASON_OFFLINE_TOO_LONG = "\u0627\u0644\u062C\u0647\u0627\u0632 \u0623\u0648\u0641\u0644\u0627\u064A\u0646 \u0645\u0646 \u0645\u062F\u0629 \u0637\u0648\u064A\u0644\u0629 \u2014 \u0644\u0627\u0632\u0645 \u064A\u062A\u0635\u0644 \u0628\u0627\u0644\u0633\u064A\u0631\u0641\u0631 \u0644\u062A\u062C\u062F\u064A\u062F \u0627\u0644\u062C\u0644\u0633\u0629";
482
+ var LOCK_REASON_ACTIVATION_EXPIRED = "\u0627\u0646\u062A\u0647\u062A \u0635\u0644\u0627\u062D\u064A\u0629 \u0645\u0641\u062A\u0627\u062D \u0627\u0644\u062A\u0641\u0639\u064A\u0644";
483
+ function deriveMode(tokenValid, meta, activation) {
484
+ if (tokenValid) return "online";
485
+ if (meta.activatedOnlineAt != null) return "offline-degraded";
486
+ if (activation != null) return "offline-activated";
487
+ return "unactivated";
488
+ }
489
+ function computeAccess(mode, now, meta, activation, policy) {
490
+ if (mode === "online") {
491
+ return { state: "active", graceEndsAt: null, lockedReason: null };
492
+ }
493
+ if (mode === "unactivated") {
494
+ return { state: "locked", graceEndsAt: null, lockedReason: LOCK_REASON_UNACTIVATED };
495
+ }
496
+ let allowanceEnd;
497
+ let graceMs;
498
+ let expiredReason;
499
+ if (mode === "offline-activated" && activation) {
500
+ allowanceEnd = activation.claims.expiresAt;
501
+ graceMs = activation.claims.graceMs ?? policy.graceMs;
502
+ expiredReason = LOCK_REASON_ACTIVATION_EXPIRED;
503
+ } else {
504
+ const anchor = meta.lastServerContactAt ?? meta.activatedOnlineAt ?? now;
505
+ allowanceEnd = anchor + policy.maxOfflineMs;
506
+ graceMs = policy.graceMs;
507
+ expiredReason = LOCK_REASON_OFFLINE_TOO_LONG;
508
+ }
509
+ if (now < allowanceEnd) {
510
+ return { state: "active", graceEndsAt: null, lockedReason: null };
511
+ }
512
+ const lockAt = allowanceEnd + graceMs;
513
+ if (now < lockAt) {
514
+ return { state: "grace", graceEndsAt: lockAt, lockedReason: null };
515
+ }
516
+ return { state: "locked", graceEndsAt: null, lockedReason: expiredReason };
517
+ }
518
+
519
+ // src/createAuth.ts
520
+ function createAuth(opts) {
521
+ const now = opts.now ?? systemClock;
522
+ const hasher = opts.hasher ?? new NoblePinHasher();
523
+ const verifier = opts.verifier ?? new NobleSignatureVerifier();
524
+ let service;
525
+ const tokens = new TokenManager({
526
+ vault: opts.vault,
527
+ api: opts.api,
528
+ now,
529
+ skewMs: opts.skewMs,
530
+ onServerContact: (at) => service.recordServerContact(at)
531
+ });
532
+ const pins = new PinManager({
533
+ directory: opts.directory,
534
+ hasher,
535
+ now,
536
+ maxAttempts: opts.maxPinAttempts,
537
+ lockoutMs: opts.pinLockoutMs
538
+ });
539
+ const activation = new ActivationManager({
540
+ vault: opts.vault,
541
+ verifier,
542
+ publicKey: opts.activationPublicKey,
543
+ now,
544
+ deviceId: opts.deviceId
545
+ });
546
+ service = new AuthService({
547
+ vault: opts.vault,
548
+ tokenManager: tokens,
549
+ pinManager: pins,
550
+ activationManager: activation,
551
+ policy: opts.policy,
552
+ now
553
+ });
554
+ return {
555
+ service,
556
+ tokens,
557
+ pins,
558
+ activation,
559
+ getValidToken: () => service.getValidToken(),
560
+ getAccessTokenSync: () => service.getAccessTokenSync()
561
+ };
562
+ }
563
+
564
+ export { ActivationManager, AuthNetworkError, AuthRejectedError, AuthService, DAY, DEFAULT_ACCESS_POLICY, HOUR, MINUTE, PinManager, SECOND, TokenManager, createAuth, systemClock };
565
+ //# sourceMappingURL=index.js.map
566
+ //# sourceMappingURL=index.js.map