@authyon/server 0.2.0-beta.0 → 0.2.0-beta.11
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/LICENSE +21 -0
- package/README.md +321 -2
- package/dist/authorization-CeP_GqT7.d.cts +129 -0
- package/dist/authorization-D_A6L9Ie.d.ts +129 -0
- package/dist/authyonServerClient-D-DxoL30.d.cts +898 -0
- package/dist/authyonServerClient-D-DxoL30.d.ts +898 -0
- package/dist/bff.cjs +1126 -0
- package/dist/bff.d.cts +142 -0
- package/dist/bff.d.ts +142 -0
- package/dist/bff.js +791 -0
- package/dist/browser.cjs +21 -0
- package/dist/browser.d.cts +2 -0
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +4 -0
- package/dist/chunk-56H66KLG.js +323 -0
- package/dist/chunk-77J4NURK.js +13 -0
- package/dist/chunk-NKWQMYB3.js +485 -0
- package/dist/index.cjs +1276 -73
- package/dist/index.d.cts +58 -506
- package/dist/index.d.ts +58 -506
- package/dist/index.js +516 -85
- package/dist/next.cjs +328 -0
- package/dist/next.d.cts +27 -0
- package/dist/next.d.ts +27 -0
- package/dist/next.js +48 -0
- package/package.json +81 -36
package/dist/next.cjs
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/next.ts
|
|
21
|
+
var next_exports = {};
|
|
22
|
+
__export(next_exports, {
|
|
23
|
+
PermissionGuard: () => PermissionGuard
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(next_exports);
|
|
26
|
+
|
|
27
|
+
// ../../internal/core/authorization/ability.ts
|
|
28
|
+
var AuthyonAbility = class {
|
|
29
|
+
constructor(rules = [], detectSubjectType = defaultSubjectType) {
|
|
30
|
+
this.detectSubjectType = detectSubjectType;
|
|
31
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
32
|
+
this.currentRules = rules.map(cloneRule);
|
|
33
|
+
}
|
|
34
|
+
get rules() {
|
|
35
|
+
return this.currentRules;
|
|
36
|
+
}
|
|
37
|
+
can(action, subject, field) {
|
|
38
|
+
const subjectType = typeof subject === "string" ? subject : this.detectSubjectType(subject);
|
|
39
|
+
for (let index = this.currentRules.length - 1; index >= 0; index -= 1) {
|
|
40
|
+
const rule = this.currentRules[index];
|
|
41
|
+
if (!matchesToken(rule.action, action, "manage")) continue;
|
|
42
|
+
if (!matchesToken(rule.subject, subjectType, "all")) continue;
|
|
43
|
+
if (field && rule.fields && !rule.fields.some((value) => matchesField(value, field)))
|
|
44
|
+
continue;
|
|
45
|
+
if (rule.conditions) {
|
|
46
|
+
if (typeof subject === "string" || !matchesConditions(subject, rule.conditions)) continue;
|
|
47
|
+
}
|
|
48
|
+
return !rule.inverted;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
cannot(action, subject, field) {
|
|
53
|
+
return !this.can(action, subject, field);
|
|
54
|
+
}
|
|
55
|
+
rulesFor(action, subject) {
|
|
56
|
+
return this.currentRules.filter(
|
|
57
|
+
(rule) => matchesToken(rule.action, action, "manage") && matchesToken(rule.subject, subject, "all")
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
update(rules) {
|
|
61
|
+
this.currentRules = rules.map(cloneRule);
|
|
62
|
+
for (const listener of this.listeners) listener(this.rules);
|
|
63
|
+
}
|
|
64
|
+
on(event, listener) {
|
|
65
|
+
if (event !== "updated") return () => void 0;
|
|
66
|
+
this.listeners.add(listener);
|
|
67
|
+
return () => this.listeners.delete(listener);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
function createAuthyonAbility(source = {}, options = {}) {
|
|
71
|
+
return new AuthyonAbility(createAuthyonRules(source, options), options.detectSubjectType);
|
|
72
|
+
}
|
|
73
|
+
function createAuthyonRules(source = {}, options = {}) {
|
|
74
|
+
const permissions = /* @__PURE__ */ new Set([
|
|
75
|
+
...source.permissions ?? [],
|
|
76
|
+
...source.scope?.split(/\s+/).filter(Boolean) ?? []
|
|
77
|
+
]);
|
|
78
|
+
const rules = [...permissions].map(permissionToRule).filter(isAbilityRule);
|
|
79
|
+
for (const role of /* @__PURE__ */ new Set([...source.roles ?? [], ...options.roles ?? []])) {
|
|
80
|
+
rules.push(...(options.roleRules?.[role] ?? []).map(cloneRule));
|
|
81
|
+
}
|
|
82
|
+
rules.push(...(options.rules ?? []).map(cloneRule));
|
|
83
|
+
return rules;
|
|
84
|
+
}
|
|
85
|
+
function permissionToRule(permission) {
|
|
86
|
+
const normalized = permission.trim();
|
|
87
|
+
if (!normalized) return null;
|
|
88
|
+
if (normalized === "*" || normalized === "*:*" || normalized === "all:manage") {
|
|
89
|
+
return { action: "manage", subject: "all" };
|
|
90
|
+
}
|
|
91
|
+
const separator = normalized.lastIndexOf(":");
|
|
92
|
+
if (separator <= 0 || separator === normalized.length - 1) return null;
|
|
93
|
+
const subject = normalized.slice(0, separator);
|
|
94
|
+
const action = normalized.slice(separator + 1);
|
|
95
|
+
return {
|
|
96
|
+
action: action === "*" ? "manage" : action,
|
|
97
|
+
subject: subject === "*" ? "all" : subject
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function matchesToken(value, expected, wildcard) {
|
|
101
|
+
return (Array.isArray(value) ? value : [value]).some(
|
|
102
|
+
(candidate) => candidate === expected || candidate === wildcard || candidate === "*" || matchesSegments(candidate, expected)
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
function matchesSegments(pattern, value) {
|
|
106
|
+
const patternSegments = pattern.split(":");
|
|
107
|
+
const valueSegments = value.split(":");
|
|
108
|
+
return patternSegments.length === valueSegments.length && patternSegments.every((segment, index) => segment === "*" || segment === valueSegments[index]);
|
|
109
|
+
}
|
|
110
|
+
function matchesField(pattern, field) {
|
|
111
|
+
if (pattern === "*" || pattern === field) return true;
|
|
112
|
+
return pattern.endsWith(".*") && field.startsWith(pattern.slice(0, -1));
|
|
113
|
+
}
|
|
114
|
+
function matchesConditions(subject, conditions) {
|
|
115
|
+
return Object.entries(conditions).every(([path, expected]) => {
|
|
116
|
+
if (path === "$and" && Array.isArray(expected)) {
|
|
117
|
+
return expected.every(
|
|
118
|
+
(condition) => matchesConditions(subject, condition)
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
if (path === "$or" && Array.isArray(expected)) {
|
|
122
|
+
return expected.some(
|
|
123
|
+
(condition) => matchesConditions(subject, condition)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return matchesValue(readPath(subject, path), expected);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function matchesValue(actual, expected) {
|
|
130
|
+
if (!isRecord(expected) || !Object.keys(expected).some((key) => key.startsWith("$"))) {
|
|
131
|
+
return isRecord(expected) && isRecord(actual) ? matchesConditions(actual, expected) : Object.is(actual, expected);
|
|
132
|
+
}
|
|
133
|
+
return Object.entries(expected).every(([operator, operand]) => {
|
|
134
|
+
switch (operator) {
|
|
135
|
+
case "$eq":
|
|
136
|
+
return Object.is(actual, operand);
|
|
137
|
+
case "$ne":
|
|
138
|
+
return !Object.is(actual, operand);
|
|
139
|
+
case "$in":
|
|
140
|
+
return Array.isArray(operand) && operand.some((value) => Object.is(actual, value));
|
|
141
|
+
case "$nin":
|
|
142
|
+
return Array.isArray(operand) && !operand.some((value) => Object.is(actual, value));
|
|
143
|
+
case "$gt":
|
|
144
|
+
return typeof actual === "number" && typeof operand === "number" && actual > operand;
|
|
145
|
+
case "$gte":
|
|
146
|
+
return typeof actual === "number" && typeof operand === "number" && actual >= operand;
|
|
147
|
+
case "$lt":
|
|
148
|
+
return typeof actual === "number" && typeof operand === "number" && actual < operand;
|
|
149
|
+
case "$lte":
|
|
150
|
+
return typeof actual === "number" && typeof operand === "number" && actual <= operand;
|
|
151
|
+
case "$exists":
|
|
152
|
+
return operand ? actual !== void 0 : actual === void 0;
|
|
153
|
+
default:
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function readPath(value, path) {
|
|
159
|
+
return path.split(".").reduce((current, part) => isRecord(current) ? current[part] : void 0, value);
|
|
160
|
+
}
|
|
161
|
+
function defaultSubjectType(subject) {
|
|
162
|
+
const explicit = subject.__type ?? subject.type ?? subject.kind;
|
|
163
|
+
if (typeof explicit === "string") return explicit;
|
|
164
|
+
const constructorName = subject.constructor?.name;
|
|
165
|
+
return typeof constructorName === "string" ? constructorName : "Object";
|
|
166
|
+
}
|
|
167
|
+
function cloneRule(rule) {
|
|
168
|
+
return {
|
|
169
|
+
...rule,
|
|
170
|
+
action: Array.isArray(rule.action) ? [...rule.action] : rule.action,
|
|
171
|
+
subject: Array.isArray(rule.subject) ? [...rule.subject] : rule.subject,
|
|
172
|
+
fields: rule.fields ? [...rule.fields] : void 0
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function isRecord(value) {
|
|
176
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
177
|
+
}
|
|
178
|
+
function isAbilityRule(value) {
|
|
179
|
+
return value !== null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/security/jwksTokenVerifier.ts
|
|
183
|
+
var import_jose = require("jose");
|
|
184
|
+
var TokenVerificationError = class extends Error {
|
|
185
|
+
constructor(code, options = {}) {
|
|
186
|
+
super(messageForCode(code));
|
|
187
|
+
this.code = code;
|
|
188
|
+
this.name = "TokenVerificationError";
|
|
189
|
+
if (options.cause !== void 0) Object.defineProperty(this, "cause", { value: options.cause });
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
function messageForCode(code) {
|
|
193
|
+
if (code === "token.key_unavailable") return "Token verification key is unavailable";
|
|
194
|
+
if (code === "token.expired") return "Token has expired";
|
|
195
|
+
if (code === "token.not_active") return "Token is not active yet";
|
|
196
|
+
return "Token verification failed";
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/integrations/authorization.ts
|
|
200
|
+
var AuthorizationError = class extends Error {
|
|
201
|
+
constructor(status, code, message) {
|
|
202
|
+
super(message);
|
|
203
|
+
this.status = status;
|
|
204
|
+
this.code = code;
|
|
205
|
+
this.name = "AuthorizationError";
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
async function authorizeToken(client, token, options = {}) {
|
|
209
|
+
if (!token) throw unauthenticated();
|
|
210
|
+
let userId;
|
|
211
|
+
let permissions = [];
|
|
212
|
+
let roles = [];
|
|
213
|
+
let scope;
|
|
214
|
+
if (options.verification === "jwks") {
|
|
215
|
+
if (!options.jwksVerifier) {
|
|
216
|
+
throw new Error("Authyon: `jwksVerifier` is required for JWKS verification");
|
|
217
|
+
}
|
|
218
|
+
let verified;
|
|
219
|
+
try {
|
|
220
|
+
verified = await options.jwksVerifier.verifyAccessToken(token);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (!(error instanceof TokenVerificationError)) throw error;
|
|
223
|
+
if (error.code === "token.key_unavailable") {
|
|
224
|
+
throw new AuthorizationError(
|
|
225
|
+
503,
|
|
226
|
+
"authorization.unavailable",
|
|
227
|
+
"Token verification is temporarily unavailable"
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
throw unauthenticated();
|
|
231
|
+
}
|
|
232
|
+
const { claims } = verified;
|
|
233
|
+
userId = claims.sub;
|
|
234
|
+
permissions = claims.permissions ?? [];
|
|
235
|
+
roles = claims.roles ?? [];
|
|
236
|
+
scope = claims.scope;
|
|
237
|
+
} else if (options.verification === "introspect") {
|
|
238
|
+
const identity = await client.introspect(token, { clientIp: options.clientIp });
|
|
239
|
+
if (!identity.active) throw unauthenticated();
|
|
240
|
+
userId = identity.sub;
|
|
241
|
+
permissions = identity.permissions ?? [];
|
|
242
|
+
roles = identity.roles ?? [];
|
|
243
|
+
scope = identity.scope;
|
|
244
|
+
} else {
|
|
245
|
+
const identity = await client.validate(token, { clientIp: options.clientIp });
|
|
246
|
+
if (!identity.valid || !identity.user) throw unauthenticated();
|
|
247
|
+
userId = identity.user.id;
|
|
248
|
+
permissions = identity.user.permissions ?? [];
|
|
249
|
+
}
|
|
250
|
+
const ability = createAuthyonAbility(
|
|
251
|
+
{ permissions, roles, scope },
|
|
252
|
+
{
|
|
253
|
+
rules: options.rules,
|
|
254
|
+
roleRules: options.roleRules,
|
|
255
|
+
roles: options.roles,
|
|
256
|
+
detectSubjectType: options.detectSubjectType
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
if (options.requirement && !canAccess(ability, options.requirement)) {
|
|
260
|
+
throw new AuthorizationError(403, "authorization.forbidden", "Permission denied");
|
|
261
|
+
}
|
|
262
|
+
return { token, userId, ability, permissions, roles };
|
|
263
|
+
}
|
|
264
|
+
function authorizeRequest(client, request, options = {}) {
|
|
265
|
+
const clientIp = options.resolveClientIp?.(request) ?? options.clientIp;
|
|
266
|
+
return authorizeToken(client, bearerToken(request.headers.get("authorization")), {
|
|
267
|
+
...options,
|
|
268
|
+
clientIp
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function canAccess(ability, requirement) {
|
|
272
|
+
return ability.can(requirement.action, requirement.subject, requirement.field);
|
|
273
|
+
}
|
|
274
|
+
function bearerToken(header) {
|
|
275
|
+
const match = header?.match(/^Bearer\s+(.+)$/i);
|
|
276
|
+
if (!match?.[1]) throw unauthenticated();
|
|
277
|
+
return match[1].trim();
|
|
278
|
+
}
|
|
279
|
+
function unauthenticated() {
|
|
280
|
+
return new AuthorizationError(
|
|
281
|
+
401,
|
|
282
|
+
"authorization.unauthenticated",
|
|
283
|
+
"A valid bearer token is required"
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// src/next.ts
|
|
288
|
+
async function PermissionGuard({
|
|
289
|
+
client,
|
|
290
|
+
action,
|
|
291
|
+
subject,
|
|
292
|
+
field,
|
|
293
|
+
children,
|
|
294
|
+
token,
|
|
295
|
+
request,
|
|
296
|
+
unauthenticatedFallback = null,
|
|
297
|
+
forbiddenFallback = null,
|
|
298
|
+
unavailableFallback,
|
|
299
|
+
...options
|
|
300
|
+
}) {
|
|
301
|
+
try {
|
|
302
|
+
await authorizeGuardRequest(client, {
|
|
303
|
+
...options,
|
|
304
|
+
request,
|
|
305
|
+
token,
|
|
306
|
+
requirement: { action, subject, field }
|
|
307
|
+
});
|
|
308
|
+
return children;
|
|
309
|
+
} catch (error) {
|
|
310
|
+
if (!(error instanceof AuthorizationError)) throw error;
|
|
311
|
+
if (error.status === 401) return renderFallback(unauthenticatedFallback, error);
|
|
312
|
+
if (error.status === 403) return renderFallback(forbiddenFallback, error);
|
|
313
|
+
if (unavailableFallback !== void 0) return renderFallback(unavailableFallback, error);
|
|
314
|
+
throw error;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function authorizeGuardRequest(client, options) {
|
|
318
|
+
const { request, token, ...authorizationOptions } = options;
|
|
319
|
+
if (request) return authorizeRequest(client, request, authorizationOptions);
|
|
320
|
+
return authorizeToken(client, token ?? "", authorizationOptions);
|
|
321
|
+
}
|
|
322
|
+
function renderFallback(fallback, error) {
|
|
323
|
+
return typeof fallback === "function" ? fallback({ error }) : fallback;
|
|
324
|
+
}
|
|
325
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
326
|
+
0 && (module.exports = {
|
|
327
|
+
PermissionGuard
|
|
328
|
+
});
|
package/dist/next.d.cts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-CeP_GqT7.cjs';
|
|
3
|
+
import { A as AuthyonServerClient } from './authyonServerClient-D-DxoL30.cjs';
|
|
4
|
+
import 'jose';
|
|
5
|
+
|
|
6
|
+
interface ServerPermissionGuardFallbackContext {
|
|
7
|
+
error: AuthorizationError;
|
|
8
|
+
}
|
|
9
|
+
type ServerPermissionGuardFallback = ReactNode | ((context: ServerPermissionGuardFallbackContext) => ReactNode | Promise<ReactNode>);
|
|
10
|
+
interface ServerPermissionGuardProps extends Omit<RequestAuthorizationOptions, "requirement"> {
|
|
11
|
+
client: AuthyonServerClient;
|
|
12
|
+
action: string;
|
|
13
|
+
subject: AbilitySubject;
|
|
14
|
+
field?: string;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
/** Bearer token already extracted from cookies, headers or session state. */
|
|
17
|
+
token?: string | null;
|
|
18
|
+
/** Web Request available in Route Handlers and other Fetch runtimes. */
|
|
19
|
+
request?: Pick<Request, "headers">;
|
|
20
|
+
unauthenticatedFallback?: ServerPermissionGuardFallback;
|
|
21
|
+
forbiddenFallback?: ServerPermissionGuardFallback;
|
|
22
|
+
unavailableFallback?: ServerPermissionGuardFallback;
|
|
23
|
+
}
|
|
24
|
+
/** Server Component guard for Next.js layouts and pages. */
|
|
25
|
+
declare function PermissionGuard({ client, action, subject, field, children, token, request, unauthenticatedFallback, forbiddenFallback, unavailableFallback, ...options }: ServerPermissionGuardProps): Promise<ReactNode>;
|
|
26
|
+
|
|
27
|
+
export { PermissionGuard, type ServerPermissionGuardFallback, type ServerPermissionGuardFallbackContext, type ServerPermissionGuardProps };
|
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { R as RequestAuthorizationOptions, A as AbilitySubject, a as AuthorizationError } from './authorization-D_A6L9Ie.js';
|
|
3
|
+
import { A as AuthyonServerClient } from './authyonServerClient-D-DxoL30.js';
|
|
4
|
+
import 'jose';
|
|
5
|
+
|
|
6
|
+
interface ServerPermissionGuardFallbackContext {
|
|
7
|
+
error: AuthorizationError;
|
|
8
|
+
}
|
|
9
|
+
type ServerPermissionGuardFallback = ReactNode | ((context: ServerPermissionGuardFallbackContext) => ReactNode | Promise<ReactNode>);
|
|
10
|
+
interface ServerPermissionGuardProps extends Omit<RequestAuthorizationOptions, "requirement"> {
|
|
11
|
+
client: AuthyonServerClient;
|
|
12
|
+
action: string;
|
|
13
|
+
subject: AbilitySubject;
|
|
14
|
+
field?: string;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
/** Bearer token already extracted from cookies, headers or session state. */
|
|
17
|
+
token?: string | null;
|
|
18
|
+
/** Web Request available in Route Handlers and other Fetch runtimes. */
|
|
19
|
+
request?: Pick<Request, "headers">;
|
|
20
|
+
unauthenticatedFallback?: ServerPermissionGuardFallback;
|
|
21
|
+
forbiddenFallback?: ServerPermissionGuardFallback;
|
|
22
|
+
unavailableFallback?: ServerPermissionGuardFallback;
|
|
23
|
+
}
|
|
24
|
+
/** Server Component guard for Next.js layouts and pages. */
|
|
25
|
+
declare function PermissionGuard({ client, action, subject, field, children, token, request, unauthenticatedFallback, forbiddenFallback, unavailableFallback, ...options }: ServerPermissionGuardProps): Promise<ReactNode>;
|
|
26
|
+
|
|
27
|
+
export { PermissionGuard, type ServerPermissionGuardFallback, type ServerPermissionGuardFallbackContext, type ServerPermissionGuardProps };
|
package/dist/next.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthorizationError,
|
|
3
|
+
authorizeRequest,
|
|
4
|
+
authorizeToken
|
|
5
|
+
} from "./chunk-NKWQMYB3.js";
|
|
6
|
+
import "./chunk-77J4NURK.js";
|
|
7
|
+
|
|
8
|
+
// src/next.ts
|
|
9
|
+
async function PermissionGuard({
|
|
10
|
+
client,
|
|
11
|
+
action,
|
|
12
|
+
subject,
|
|
13
|
+
field,
|
|
14
|
+
children,
|
|
15
|
+
token,
|
|
16
|
+
request,
|
|
17
|
+
unauthenticatedFallback = null,
|
|
18
|
+
forbiddenFallback = null,
|
|
19
|
+
unavailableFallback,
|
|
20
|
+
...options
|
|
21
|
+
}) {
|
|
22
|
+
try {
|
|
23
|
+
await authorizeGuardRequest(client, {
|
|
24
|
+
...options,
|
|
25
|
+
request,
|
|
26
|
+
token,
|
|
27
|
+
requirement: { action, subject, field }
|
|
28
|
+
});
|
|
29
|
+
return children;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (!(error instanceof AuthorizationError)) throw error;
|
|
32
|
+
if (error.status === 401) return renderFallback(unauthenticatedFallback, error);
|
|
33
|
+
if (error.status === 403) return renderFallback(forbiddenFallback, error);
|
|
34
|
+
if (unavailableFallback !== void 0) return renderFallback(unavailableFallback, error);
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function authorizeGuardRequest(client, options) {
|
|
39
|
+
const { request, token, ...authorizationOptions } = options;
|
|
40
|
+
if (request) return authorizeRequest(client, request, authorizationOptions);
|
|
41
|
+
return authorizeToken(client, token ?? "", authorizationOptions);
|
|
42
|
+
}
|
|
43
|
+
function renderFallback(fallback, error) {
|
|
44
|
+
return typeof fallback === "function" ? fallback({ error }) : fallback;
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
PermissionGuard
|
|
48
|
+
};
|
package/package.json
CHANGED
|
@@ -1,36 +1,81 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@authyon/server",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
4
|
-
"description": "Authyon SDK for backends — server-to-server organization/member management and access-token verification.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@authyon/server",
|
|
3
|
+
"version": "0.2.0-beta.11",
|
|
4
|
+
"description": "Authyon SDK for backends — server-to-server organization/member management and access-token verification.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=18"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/Synkestra/package-authyon.git",
|
|
13
|
+
"directory": "packages/server"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://authyon.com/docs",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/Synkestra/package-authyon/issues"
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/index.cjs",
|
|
20
|
+
"module": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"browser": "./dist/browser.js",
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"require": "./dist/index.cjs",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./bff": {
|
|
31
|
+
"types": "./dist/bff.d.ts",
|
|
32
|
+
"browser": "./dist/browser.js",
|
|
33
|
+
"import": "./dist/bff.js",
|
|
34
|
+
"require": "./dist/bff.cjs",
|
|
35
|
+
"default": "./dist/bff.js"
|
|
36
|
+
},
|
|
37
|
+
"./next": {
|
|
38
|
+
"types": "./dist/next.d.ts",
|
|
39
|
+
"import": "./dist/next.js",
|
|
40
|
+
"require": "./dist/next.cjs",
|
|
41
|
+
"default": "./dist/next.js"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist"
|
|
46
|
+
],
|
|
47
|
+
"sideEffects": false,
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public",
|
|
50
|
+
"provenance": true
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup src/index.ts src/browser.ts src/next.ts src/bff.ts --format esm,cjs --dts --clean",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"prepack": "npm run build"
|
|
56
|
+
},
|
|
57
|
+
"keywords": [
|
|
58
|
+
"authyon",
|
|
59
|
+
"auth",
|
|
60
|
+
"server-to-server",
|
|
61
|
+
"management-api",
|
|
62
|
+
"tokenVerification"
|
|
63
|
+
],
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"jose": "^6.2.10"
|
|
66
|
+
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"react": ">=18.2.0"
|
|
69
|
+
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"react": {
|
|
72
|
+
"optional": true
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@types/node": "^22.20.2",
|
|
77
|
+
"@types/react": "^19.2.18",
|
|
78
|
+
"tsup": "^8.0.0",
|
|
79
|
+
"typescript": "^5.5.0"
|
|
80
|
+
}
|
|
81
|
+
}
|