@authyon/auth 0.2.0-beta.2 → 0.2.0-beta.20
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 +62 -21
- package/dist/{ability-g6nBpOQM.d.cts → ability-BTcayvkM.d.cts} +324 -10
- package/dist/{ability-g6nBpOQM.d.ts → ability-BTcayvkM.d.ts} +324 -10
- package/dist/{chunk-EHZEUM47.js → chunk-3XJY6BCI.js} +6 -0
- package/dist/index.cjs +227 -35
- package/dist/index.d.cts +48 -21
- package/dist/index.d.ts +48 -21
- package/dist/index.js +217 -30
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,8 +4,40 @@ import {
|
|
|
4
4
|
AuthyonSessionController,
|
|
5
5
|
createAuthyonAbility,
|
|
6
6
|
createAuthyonRules,
|
|
7
|
-
hasPermission
|
|
8
|
-
|
|
7
|
+
hasPermission,
|
|
8
|
+
hasPermissionGroup
|
|
9
|
+
} from "./chunk-3XJY6BCI.js";
|
|
10
|
+
|
|
11
|
+
// ../../internal/core/security/approvals.ts
|
|
12
|
+
function path(id, suffix = "") {
|
|
13
|
+
if (typeof id !== "string" || !id.trim())
|
|
14
|
+
throw new TypeError("Authyon: an approval id is required.");
|
|
15
|
+
return `/auth/authorizations/${encodeURIComponent(id)}${suffix}`;
|
|
16
|
+
}
|
|
17
|
+
var NO_METHODS = {
|
|
18
|
+
password: false,
|
|
19
|
+
authenticator: false,
|
|
20
|
+
emailCode: false,
|
|
21
|
+
passkey: false,
|
|
22
|
+
passkeyCount: 0,
|
|
23
|
+
recoveryCodes: 0,
|
|
24
|
+
sso: [],
|
|
25
|
+
twoFactor: false
|
|
26
|
+
};
|
|
27
|
+
function subjectSecurity(request) {
|
|
28
|
+
return {
|
|
29
|
+
methods: async () => {
|
|
30
|
+
const me = await request("/auth/me");
|
|
31
|
+
return me.security ?? NO_METHODS;
|
|
32
|
+
},
|
|
33
|
+
approvals: {
|
|
34
|
+
get: (id) => request(path(id)),
|
|
35
|
+
webauthnOptions: (id) => request(path(id, "/webauthn/options"), { method: "POST" }),
|
|
36
|
+
confirm: (id, input) => request(path(id, "/confirm"), { method: "POST", body: input }),
|
|
37
|
+
reject: (id) => request(path(id, "/reject"), { method: "POST" })
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
9
41
|
|
|
10
42
|
// ../../internal/core/errors/authyonError.ts
|
|
11
43
|
var ErrorCodes = {
|
|
@@ -19,16 +51,45 @@ var ErrorCodes = {
|
|
|
19
51
|
EmailTaken: "user.email_taken",
|
|
20
52
|
PasswordWeak: "user.password_weak",
|
|
21
53
|
PasswordPwned: "user.password_pwned",
|
|
22
|
-
RateLimited: "rate_limited"
|
|
54
|
+
RateLimited: "rate_limited",
|
|
55
|
+
StepUpRequired: "step_up_required",
|
|
56
|
+
InvalidSecondFactorCode: "invalid_code",
|
|
57
|
+
VerificationAttemptsExhausted: "verification_attempts_exhausted",
|
|
58
|
+
MethodNotEnrolled: "method_not_enrolled",
|
|
59
|
+
InvalidApprovalState: "invalid_authorization_state",
|
|
60
|
+
PayloadMismatch: "payload_mismatch",
|
|
61
|
+
ApprovalNotConsumable: "authorization_not_consumable",
|
|
62
|
+
IdempotencyConflict: "idempotency_conflict",
|
|
63
|
+
UserDisabled: "user_disabled",
|
|
64
|
+
UserNotFound: "user_not_found",
|
|
65
|
+
TemporarilyUnavailable: "temporarily_unavailable",
|
|
66
|
+
InsufficientScope: "insufficient_scope",
|
|
67
|
+
CredentialThrottled: "credential_throttled",
|
|
68
|
+
ApprovalNotFound: "authorization_not_found",
|
|
69
|
+
SessionRevoked: "session_revoked",
|
|
70
|
+
TwoFactorTooManyFailures: "user.2fa.too_many_failures"
|
|
23
71
|
};
|
|
72
|
+
var STANDARD_ERROR_FIELDS = /* @__PURE__ */ new Set([
|
|
73
|
+
"type",
|
|
74
|
+
"status",
|
|
75
|
+
"title",
|
|
76
|
+
"detail",
|
|
77
|
+
"code",
|
|
78
|
+
"error",
|
|
79
|
+
"error_description"
|
|
80
|
+
]);
|
|
24
81
|
var AuthyonError = class extends Error {
|
|
25
82
|
constructor(status, body, options = {}) {
|
|
26
|
-
|
|
83
|
+
const detail = body.detail ?? body.error_description;
|
|
84
|
+
super(detail ?? body.title ?? `Authyon request failed with status ${status}`);
|
|
27
85
|
this.name = "AuthyonError";
|
|
28
86
|
this.status = status;
|
|
29
|
-
this.code = body.code ?? "unknown";
|
|
87
|
+
this.code = body.code ?? body.error ?? "unknown";
|
|
30
88
|
this.title = body.title ?? "Error";
|
|
31
|
-
this.detail =
|
|
89
|
+
this.detail = detail;
|
|
90
|
+
this.extensions = Object.fromEntries(
|
|
91
|
+
Object.entries(body).filter(([key]) => !STANDARD_ERROR_FIELDS.has(key))
|
|
92
|
+
);
|
|
32
93
|
this.requestId = options.requestId;
|
|
33
94
|
this.retryAfter = options.retryAfter;
|
|
34
95
|
this.cause = options.cause;
|
|
@@ -78,6 +139,7 @@ var AuthyonError = class extends Error {
|
|
|
78
139
|
};
|
|
79
140
|
function classifyError(status, code) {
|
|
80
141
|
if (code === ErrorCodes.NetworkError) return "network";
|
|
142
|
+
if (code === ErrorCodes.StepUpRequired) return "authentication";
|
|
81
143
|
if (code === ErrorCodes.Timeout || status === 408) return "timeout";
|
|
82
144
|
if (code === ErrorCodes.RateLimited || status === 429) return "rate_limit";
|
|
83
145
|
if (code === ErrorCodes.EmailTaken || status === 409) return "conflict";
|
|
@@ -171,14 +233,14 @@ var DEFAULT_BASE_URL = "https://api.authyon.com";
|
|
|
171
233
|
var DEFAULT_EXPIRY_SKEW_MS = 3e4;
|
|
172
234
|
|
|
173
235
|
// ../../internal/core/http/query.ts
|
|
174
|
-
function appendQuery(
|
|
175
|
-
if (!params) return
|
|
236
|
+
function appendQuery(path2, params) {
|
|
237
|
+
if (!params) return path2;
|
|
176
238
|
const query = new URLSearchParams();
|
|
177
239
|
for (const [key, value2] of Object.entries(params)) {
|
|
178
240
|
if (value2 !== void 0) query.set(key, String(value2));
|
|
179
241
|
}
|
|
180
242
|
const value = query.toString();
|
|
181
|
-
return value ? `${
|
|
243
|
+
return value ? `${path2}${path2.includes("?") ? "&" : "?"}${value}` : path2;
|
|
182
244
|
}
|
|
183
245
|
|
|
184
246
|
// ../../internal/core/http/httpAdapter.ts
|
|
@@ -191,7 +253,8 @@ var FetchHttpAdapter = class {
|
|
|
191
253
|
method: request.method,
|
|
192
254
|
headers: request.headers,
|
|
193
255
|
body: request.body,
|
|
194
|
-
signal: request.signal
|
|
256
|
+
signal: request.signal,
|
|
257
|
+
redirect: "error"
|
|
195
258
|
});
|
|
196
259
|
}
|
|
197
260
|
};
|
|
@@ -243,6 +306,9 @@ function defaultHttpLogger(event) {
|
|
|
243
306
|
}
|
|
244
307
|
function sanitizeUrl(value) {
|
|
245
308
|
const url = new URL(value);
|
|
309
|
+
url.username = "";
|
|
310
|
+
url.password = "";
|
|
311
|
+
url.hash = "";
|
|
246
312
|
const queryKeys = /* @__PURE__ */ new Set();
|
|
247
313
|
url.searchParams.forEach((_value, key) => queryKeys.add(key));
|
|
248
314
|
url.search = queryKeys.size > 0 ? [...queryKeys].map((key) => `${encodeURIComponent(key)}=REDACTED`).join("&") : "";
|
|
@@ -272,12 +338,12 @@ function createSharedTransport(options) {
|
|
|
272
338
|
const httpAdapter = options.httpLogger ? new LoggingHttpAdapter(baseAdapter, options.httpLogger) : baseAdapter;
|
|
273
339
|
return {
|
|
274
340
|
baseUrl,
|
|
275
|
-
async request(
|
|
341
|
+
async request(path2, init) {
|
|
276
342
|
const controller = new AbortController();
|
|
277
343
|
const timeout = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : void 0;
|
|
278
344
|
try {
|
|
279
345
|
return await httpAdapter.request({
|
|
280
|
-
url: `${baseUrl}${
|
|
346
|
+
url: `${baseUrl}${path2}`,
|
|
281
347
|
method: init.method ?? "GET",
|
|
282
348
|
headers: normalizeHeaders(init.headers),
|
|
283
349
|
body: init.body,
|
|
@@ -335,11 +401,11 @@ var JsonHttpClient = class {
|
|
|
335
401
|
constructor(transport) {
|
|
336
402
|
this.transport = transport;
|
|
337
403
|
}
|
|
338
|
-
async send(
|
|
404
|
+
async send(path2, options = {}) {
|
|
339
405
|
const headers = { ...options.headers };
|
|
340
406
|
if (options.body !== void 0) headers["Content-Type"] = "application/json";
|
|
341
407
|
try {
|
|
342
|
-
return await this.transport.request(appendQuery(
|
|
408
|
+
return await this.transport.request(appendQuery(path2, options.query), {
|
|
343
409
|
method: options.method ?? "GET",
|
|
344
410
|
headers,
|
|
345
411
|
body: options.body !== void 0 ? JSON.stringify(options.body) : void 0
|
|
@@ -353,7 +419,9 @@ var JsonHttpClient = class {
|
|
|
353
419
|
if (!response.ok) {
|
|
354
420
|
let body = {};
|
|
355
421
|
try {
|
|
356
|
-
|
|
422
|
+
const parsed = await response.json();
|
|
423
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
424
|
+
body = parsed;
|
|
357
425
|
} catch {
|
|
358
426
|
}
|
|
359
427
|
throw new AuthyonError(response.status, body, responseMetadata(response));
|
|
@@ -361,11 +429,33 @@ var JsonHttpClient = class {
|
|
|
361
429
|
if (response.status === 204) return void 0;
|
|
362
430
|
return await response.json();
|
|
363
431
|
}
|
|
364
|
-
async request(
|
|
365
|
-
return this.parse(await this.send(
|
|
432
|
+
async request(path2, options = {}) {
|
|
433
|
+
return this.parse(await this.send(path2, options));
|
|
366
434
|
}
|
|
367
435
|
};
|
|
368
436
|
|
|
437
|
+
// ../../internal/core/http/clientIp.ts
|
|
438
|
+
function clientIpHeaders(context) {
|
|
439
|
+
if (!context?.clientIp) return {};
|
|
440
|
+
return { "X-Forwarded-For": normalizeClientIp(context.clientIp) };
|
|
441
|
+
}
|
|
442
|
+
function normalizeClientIp(value) {
|
|
443
|
+
let ip = value.trim();
|
|
444
|
+
if (ip.startsWith("[") && ip.endsWith("]")) ip = ip.slice(1, -1);
|
|
445
|
+
if (!ip || ip.length > 45 || ip.includes(",") || /[\r\n\s]/.test(ip) || !/^[0-9a-f:.]+$/i.test(ip) || !ip.includes(".") && !ip.includes(":")) {
|
|
446
|
+
throw invalidClientIp();
|
|
447
|
+
}
|
|
448
|
+
try {
|
|
449
|
+
new URL(ip.includes(":") ? `http://[${ip}]` : `http://${ip}`);
|
|
450
|
+
} catch {
|
|
451
|
+
throw invalidClientIp();
|
|
452
|
+
}
|
|
453
|
+
return ip;
|
|
454
|
+
}
|
|
455
|
+
function invalidClientIp() {
|
|
456
|
+
return new Error("Authyon: `clientIp` must be a single valid IPv4 or IPv6 address");
|
|
457
|
+
}
|
|
458
|
+
|
|
369
459
|
// src/client/authyonClient.ts
|
|
370
460
|
var FALLBACK_EXPIRES_IN = 1800;
|
|
371
461
|
function readTokens(raw) {
|
|
@@ -443,18 +533,41 @@ var AuthyonClient = class {
|
|
|
443
533
|
method: "DELETE",
|
|
444
534
|
bearer: true
|
|
445
535
|
}),
|
|
446
|
-
/**
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
536
|
+
/**
|
|
537
|
+
* POST /auth/password-reset/request — resolves whether or not the address
|
|
538
|
+
* has an account (no account enumeration). `redirectUri` is where the
|
|
539
|
+
* person lands after changing the password; it must be one of the
|
|
540
|
+
* environment's registered redirect URIs, or the call rejects with
|
|
541
|
+
* `user.password_reset.redirect_uri.not_allowed`.
|
|
542
|
+
*/
|
|
543
|
+
requestPasswordReset: (email, options = {}) => this.request("/auth/password-reset/request", {
|
|
450
544
|
method: "POST",
|
|
451
|
-
body: {
|
|
452
|
-
})
|
|
545
|
+
body: { email, ...options }
|
|
546
|
+
}),
|
|
547
|
+
/**
|
|
548
|
+
* POST /auth/password-reset/validate — checks a reset token without
|
|
549
|
+
* spending it, so the reset page can refuse a dead link before asking for
|
|
550
|
+
* a password. Rejects with `user.password_reset.invalid` (401) when the
|
|
551
|
+
* token is unknown, used or expired.
|
|
552
|
+
*/
|
|
553
|
+
validatePasswordReset: (token) => this.request("/auth/password-reset/validate", { method: "POST", body: { token } }),
|
|
554
|
+
/**
|
|
555
|
+
* POST /auth/password-reset/confirm — sets a new password and revokes all
|
|
556
|
+
* refresh tokens. Resolves with the `redirectUri` the reset was requested
|
|
557
|
+
* with (`null` when there was none); following it is up to the caller.
|
|
558
|
+
*/
|
|
559
|
+
confirmPasswordReset: async (token, newPassword) => {
|
|
560
|
+
const done = await this.request(
|
|
561
|
+
"/auth/password-reset/confirm",
|
|
562
|
+
{ method: "POST", body: { token, newPassword } }
|
|
563
|
+
);
|
|
564
|
+
return { redirectUri: done?.redirectUri ?? null };
|
|
565
|
+
}
|
|
453
566
|
};
|
|
454
567
|
// ── Organization ─────────────────────────────────────────────────────────
|
|
455
568
|
this.organization = {
|
|
456
|
-
/** GET /auth/tenants —
|
|
457
|
-
list: () => this.request("/auth/tenants", { bearer: true }),
|
|
569
|
+
/** GET /auth/tenants — filterable list of organization memberships. */
|
|
570
|
+
list: (params = {}) => this.request(appendQuery("/auth/tenants", params), { bearer: true }),
|
|
458
571
|
/**
|
|
459
572
|
* POST /auth/tenants — creates an organization owned by the signed-in
|
|
460
573
|
* user (only available when self-service organization creation is
|
|
@@ -491,7 +604,11 @@ var AuthyonClient = class {
|
|
|
491
604
|
appendQuery(`/auth/tenants/${encodeURIComponent(organizationId)}/members`, params),
|
|
492
605
|
{ bearer: true }
|
|
493
606
|
),
|
|
494
|
-
/**
|
|
607
|
+
/**
|
|
608
|
+
* POST /auth/tenants/{organizationId}/members — add an existing
|
|
609
|
+
* environment user by e-mail (no e-mail is sent). To invite an address
|
|
610
|
+
* that may not have an account yet, use `organization.invites.create`.
|
|
611
|
+
*/
|
|
495
612
|
invite: (organizationId, params) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/members`, {
|
|
496
613
|
method: "POST",
|
|
497
614
|
bearer: true,
|
|
@@ -503,6 +620,59 @@ var AuthyonClient = class {
|
|
|
503
620
|
{ method: "DELETE", bearer: true }
|
|
504
621
|
)
|
|
505
622
|
},
|
|
623
|
+
/**
|
|
624
|
+
* Invites by e-mail or by link. Managing them requires the
|
|
625
|
+
* `tenants:members:invite` permission on the organization; `preview` and
|
|
626
|
+
* `accept` are public — the token in the link is the credential.
|
|
627
|
+
*/
|
|
628
|
+
invites: {
|
|
629
|
+
/** GET /auth/tenants/{organizationId}/invites — every invite with its status, newest first. */
|
|
630
|
+
list: (organizationId) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/invites`, {
|
|
631
|
+
bearer: true
|
|
632
|
+
}),
|
|
633
|
+
/**
|
|
634
|
+
* POST /auth/tenants/{organizationId}/invites — invite an address.
|
|
635
|
+
* Always returns `acceptUrl`; with `sendEmail: false` Authyon does not
|
|
636
|
+
* mail it and you deliver the link yourself. The link is valid for 7
|
|
637
|
+
* days, once, and can't be read again later.
|
|
638
|
+
*/
|
|
639
|
+
create: (organizationId, params) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/invites`, {
|
|
640
|
+
method: "POST",
|
|
641
|
+
bearer: true,
|
|
642
|
+
body: {
|
|
643
|
+
email: params.email,
|
|
644
|
+
roles: params.roles,
|
|
645
|
+
sendEmail: params.sendEmail ?? true,
|
|
646
|
+
redirectUri: params.redirectUri
|
|
647
|
+
}
|
|
648
|
+
}),
|
|
649
|
+
/**
|
|
650
|
+
* POST /auth/tenants/{organizationId}/invites/{inviteId}/resend — issue
|
|
651
|
+
* a new link (the previous one stops working), mailing it unless
|
|
652
|
+
* `sendEmail` is `false`.
|
|
653
|
+
*/
|
|
654
|
+
resend: (organizationId, inviteId, params = {}) => this.request(
|
|
655
|
+
`/auth/tenants/${encodeURIComponent(organizationId)}/invites/${encodeURIComponent(inviteId)}/resend`,
|
|
656
|
+
{ method: "POST", bearer: true, body: { sendEmail: params.sendEmail ?? true } }
|
|
657
|
+
),
|
|
658
|
+
/** DELETE /auth/tenants/{organizationId}/invites/{inviteId} — revoke a pending invite. */
|
|
659
|
+
revoke: (organizationId, inviteId) => this.request(
|
|
660
|
+
`/auth/tenants/${encodeURIComponent(organizationId)}/invites/${encodeURIComponent(inviteId)}`,
|
|
661
|
+
{ method: "DELETE", bearer: true }
|
|
662
|
+
),
|
|
663
|
+
/**
|
|
664
|
+
* POST /auth/tenant-invites/preview — public. Read the `token` query
|
|
665
|
+
* parameter of the invite link and pick the form: one click when
|
|
666
|
+
* `accountExists`, sign-up otherwise.
|
|
667
|
+
*/
|
|
668
|
+
preview: (token) => this.request("/auth/tenant-invites/preview", { method: "POST", body: { token } }),
|
|
669
|
+
/**
|
|
670
|
+
* POST /auth/tenant-invites/accept — public. Joins the organization; for
|
|
671
|
+
* an address with no account, also creates it (password required) with
|
|
672
|
+
* the e-mail already confirmed. Does not sign the user in.
|
|
673
|
+
*/
|
|
674
|
+
accept: (params) => this.request("/auth/tenant-invites/accept", { method: "POST", body: params })
|
|
675
|
+
},
|
|
506
676
|
roles: {
|
|
507
677
|
/** GET /auth/tenants/{organizationId}/roles — roles available in the organization. */
|
|
508
678
|
list: (organizationId) => this.request(`/auth/tenants/${encodeURIComponent(organizationId)}/roles`, {
|
|
@@ -578,9 +748,20 @@ var AuthyonClient = class {
|
|
|
578
748
|
})
|
|
579
749
|
}
|
|
580
750
|
};
|
|
751
|
+
// ── Security (customer side) ─────────────────────────────────────────────
|
|
752
|
+
/**
|
|
753
|
+
* `security.approvals`: approve or reject what your backend asked the
|
|
754
|
+
* customer to confirm (`@authyon/server` → `security.approvals.create`).
|
|
755
|
+
* Show the payload with `get()`, then `confirm()` with the customer's
|
|
756
|
+
* authenticator code or passkey, or `reject()`.
|
|
757
|
+
*/
|
|
758
|
+
this.security = subjectSecurity(
|
|
759
|
+
(path2, options) => this.request(path2, { ...options, bearer: true })
|
|
760
|
+
);
|
|
581
761
|
if (!options.envKey)
|
|
582
762
|
throw new Error("Authyon: `envKey` is required (pk_live_... / pk_test_...)");
|
|
583
763
|
this.envKey = options.envKey;
|
|
764
|
+
this.clientIp = options.clientIp;
|
|
584
765
|
this.transport = createSharedTransport({
|
|
585
766
|
baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
|
|
586
767
|
allowInsecureHttp: options.allowInsecureHttp,
|
|
@@ -690,9 +871,10 @@ var AuthyonClient = class {
|
|
|
690
871
|
}
|
|
691
872
|
}
|
|
692
873
|
// ── HTTP core ────────────────────────────────────────────────────────────
|
|
693
|
-
async request(
|
|
874
|
+
async request(path2, options = {}, isRetry = false) {
|
|
694
875
|
const headers = {
|
|
695
876
|
"X-Authyon-Environment": this.envKey,
|
|
877
|
+
...clientIpHeaders({ clientIp: this.clientIp }),
|
|
696
878
|
...options.headers
|
|
697
879
|
};
|
|
698
880
|
if (options.bearer) {
|
|
@@ -704,7 +886,7 @@ var AuthyonClient = class {
|
|
|
704
886
|
});
|
|
705
887
|
headers.Authorization = `Bearer ${token}`;
|
|
706
888
|
}
|
|
707
|
-
const response = await this.http.send(
|
|
889
|
+
const response = await this.http.send(path2, { ...options, headers });
|
|
708
890
|
if (response.status === 401 && options.bearer && this.autoRefresh && !isRetry && this.getSession()) {
|
|
709
891
|
try {
|
|
710
892
|
await this.refresh();
|
|
@@ -712,7 +894,7 @@ var AuthyonClient = class {
|
|
|
712
894
|
this.clearSession();
|
|
713
895
|
return this.http.parse(response);
|
|
714
896
|
}
|
|
715
|
-
return this.request(
|
|
897
|
+
return this.request(path2, options, true);
|
|
716
898
|
}
|
|
717
899
|
return this.http.parse(response);
|
|
718
900
|
}
|
|
@@ -857,6 +1039,10 @@ var AuthyonClientBuilder = class {
|
|
|
857
1039
|
this.options.autoRefresh = enabled;
|
|
858
1040
|
return this;
|
|
859
1041
|
}
|
|
1042
|
+
withClientIp(clientIp) {
|
|
1043
|
+
this.options.clientIp = clientIp;
|
|
1044
|
+
return this;
|
|
1045
|
+
}
|
|
860
1046
|
withTimeout(timeoutMs) {
|
|
861
1047
|
this.options.timeoutMs = timeoutMs;
|
|
862
1048
|
return this;
|
|
@@ -889,5 +1075,6 @@ export {
|
|
|
889
1075
|
createDefaultStorage,
|
|
890
1076
|
createLocalStorage,
|
|
891
1077
|
createMemoryStorage,
|
|
892
|
-
hasPermission
|
|
1078
|
+
hasPermission,
|
|
1079
|
+
hasPermissionGroup
|
|
893
1080
|
};
|
package/dist/react/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
3
|
+
import { ac as User, a1 as SessionControllerOptions, A as AuthyonClient, a3 as SessionSnapshot, a0 as Session, f as AbilitySubject, t as AuthyonAbilityOptions, r as AuthyonAbility } from '../ability-BTcayvkM.cjs';
|
|
4
|
+
export { w as AuthyonSessionController, a4 as SessionSnapshotListener, a5 as SessionStatus } from '../ability-BTcayvkM.cjs';
|
|
5
5
|
|
|
6
6
|
interface AuthyonProviderProps<TUser extends User = User> extends SessionControllerOptions {
|
|
7
7
|
client: AuthyonClient;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
3
|
+
import { ac as User, a1 as SessionControllerOptions, A as AuthyonClient, a3 as SessionSnapshot, a0 as Session, f as AbilitySubject, t as AuthyonAbilityOptions, r as AuthyonAbility } from '../ability-BTcayvkM.js';
|
|
4
|
+
export { w as AuthyonSessionController, a4 as SessionSnapshotListener, a5 as SessionStatus } from '../ability-BTcayvkM.js';
|
|
5
5
|
|
|
6
6
|
interface AuthyonProviderProps<TUser extends User = User> extends SessionControllerOptions {
|
|
7
7
|
client: AuthyonClient;
|
package/dist/react/index.js
CHANGED