@run402/functions 2.9.0 → 3.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/auth/errors.d.ts +106 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +205 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/index.d.ts +112 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +585 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/types.d.ts +86 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +13 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/url-validation.d.ts +31 -0
- package/dist/auth/url-validation.d.ts.map +1 -0
- package/dist/auth/url-validation.js +83 -0
- package/dist/auth/url-validation.js.map +1 -0
- package/dist/auth.d.ts +25 -50
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +34 -103
- package/dist/auth.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +40 -0
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/actor-context-verify.d.ts +95 -0
- package/dist/lib/actor-context-verify.d.ts.map +1 -0
- package/dist/lib/actor-context-verify.js +200 -0
- package/dist/lib/actor-context-verify.js.map +1 -0
- package/dist/runtime-context.d.ts +23 -1
- package/dist/runtime-context.d.ts.map +1 -1
- package/dist/runtime-context.js +64 -0
- package/dist/runtime-context.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured errors thrown by the `auth.*` namespace.
|
|
3
|
+
*
|
|
4
|
+
* The platform error envelope (`R402_AUTH_*` codes) is the wire shape;
|
|
5
|
+
* these Error subclasses are how user code catches them in TypeScript.
|
|
6
|
+
*
|
|
7
|
+
* The docs say "do not catch auth errors" — the platform's response-shape
|
|
8
|
+
* decision (303 redirect for HTML, 401/403 envelope for JSON) already does
|
|
9
|
+
* the right thing. But framework code, middleware, and test harnesses
|
|
10
|
+
* occasionally need typed catches; that's what these classes are for.
|
|
11
|
+
*/
|
|
12
|
+
export type Run402AuthCode = "R402_AUTH_REQUIRED" | "R402_AUTH_INSUFFICIENT_ROLE" | "R402_AUTH_INSUFFICIENT_MEMBERSHIP" | "R402_AUTH_FRESHNESS_REQUIRED" | "R402_AUTH_PRERENDERED" | "R402_AUTH_FETCH_ABSOLUTE_URL" | "R402_AUTH_UNKNOWN_EXPORT" | "R402_AUTH_SESSION_BRIDGE_UNVERIFIED" | "R402_AUTH_IDENTITY_LINK_CONFLICT" | "R402_AUTH_UNKNOWN_IDENTITY" | "R402_AUTH_TENANT_SUFFIX_REQUIRED" | "R402_AUTH_RETURN_TO_INVALID" | "R402_AUTH_REDUNDANT_USER_FILTER" | "R402_AUTH_INVALID_CREDENTIALS" | "R402_AUTH_TENANT_SUBJECT_INVALID" | "R402_AUTH_UNTRUSTED_CONTEXT";
|
|
13
|
+
export declare class Run402AuthError extends Error {
|
|
14
|
+
readonly code: Run402AuthCode;
|
|
15
|
+
readonly status: number;
|
|
16
|
+
readonly details: Record<string, unknown>;
|
|
17
|
+
readonly suggestedFix?: string;
|
|
18
|
+
readonly docs?: string;
|
|
19
|
+
constructor(opts: {
|
|
20
|
+
code: Run402AuthCode;
|
|
21
|
+
status: number;
|
|
22
|
+
message: string;
|
|
23
|
+
details?: Record<string, unknown>;
|
|
24
|
+
suggestedFix?: string;
|
|
25
|
+
docs?: string;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Subclass identifying the "anonymous on a protected route" case. The
|
|
29
|
+
* middleware decides whether to surface this as a 303 (HTML) or a 401
|
|
30
|
+
* envelope (JSON); user code never needs to make that choice. */
|
|
31
|
+
export declare class AuthRequiredError extends Run402AuthError {
|
|
32
|
+
constructor(opts?: {
|
|
33
|
+
returnTo?: string;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
export declare class InsufficientRoleError extends Run402AuthError {
|
|
37
|
+
readonly requiredRole: string;
|
|
38
|
+
constructor(requiredRole: string);
|
|
39
|
+
}
|
|
40
|
+
export declare class InsufficientMembershipError extends Run402AuthError {
|
|
41
|
+
readonly requiredMembership: string;
|
|
42
|
+
constructor(requiredMembership: string);
|
|
43
|
+
}
|
|
44
|
+
export declare class FreshnessRequiredError extends Run402AuthError {
|
|
45
|
+
readonly maxAge: string;
|
|
46
|
+
readonly amr: string[];
|
|
47
|
+
constructor(opts: {
|
|
48
|
+
maxAge: string;
|
|
49
|
+
amr: string[];
|
|
50
|
+
returnTo?: string;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export declare class FetchAbsoluteUrlError extends Run402AuthError {
|
|
54
|
+
constructor(opts: {
|
|
55
|
+
attempted: string;
|
|
56
|
+
reason: string;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export declare class PrerenderedError extends Run402AuthError {
|
|
60
|
+
constructor(opts: {
|
|
61
|
+
sdkFunction: string;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export declare class UnknownExportError extends Run402AuthError {
|
|
65
|
+
readonly attemptedName: string;
|
|
66
|
+
readonly canonicalName: string;
|
|
67
|
+
constructor(opts: {
|
|
68
|
+
attemptedName: string;
|
|
69
|
+
canonicalName: string;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export declare class SessionBridgeUnverifiedError extends Run402AuthError {
|
|
73
|
+
constructor(opts: {
|
|
74
|
+
reason: string;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export declare class IdentityLinkConflictError extends Run402AuthError {
|
|
78
|
+
constructor(opts: {
|
|
79
|
+
provider: string;
|
|
80
|
+
subject: string;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
export declare class UnknownIdentityError extends Run402AuthError {
|
|
84
|
+
constructor(opts: {
|
|
85
|
+
provider: string;
|
|
86
|
+
subject: string;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** The canonical "your own credential check failed" error. Thrown via the
|
|
90
|
+
* `auth.invalidCredentials()` FUNCTION (not `new auth.InvalidCredentialsError()`)
|
|
91
|
+
* per D9 — agents fumble the constructor+import; `throw auth.invalidCredentials()`
|
|
92
|
+
* is one call and renders the canonical `R402_AUTH_INVALID_CREDENTIALS` envelope
|
|
93
|
+
* (distinct from `R402_AUTH_MAGIC_LINK_INVALID`). */
|
|
94
|
+
export declare class InvalidCredentialsError extends Run402AuthError {
|
|
95
|
+
constructor();
|
|
96
|
+
}
|
|
97
|
+
/** Rejects a tenant-assertion mint whose `user` lacks a stable `id` (e.g. a
|
|
98
|
+
* bare email). The `fix` shows the required `{ tenant, user: { id, email, ... },
|
|
99
|
+
* method }` shape. SDK-side fast-feedback twin of the gateway's
|
|
100
|
+
* `R402_AUTH_TENANT_SUBJECT_INVALID` envelope. */
|
|
101
|
+
export declare class TenantSubjectInvalidError extends Run402AuthError {
|
|
102
|
+
constructor(opts: {
|
|
103
|
+
reason: string;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured errors thrown by the `auth.*` namespace.
|
|
3
|
+
*
|
|
4
|
+
* The platform error envelope (`R402_AUTH_*` codes) is the wire shape;
|
|
5
|
+
* these Error subclasses are how user code catches them in TypeScript.
|
|
6
|
+
*
|
|
7
|
+
* The docs say "do not catch auth errors" — the platform's response-shape
|
|
8
|
+
* decision (303 redirect for HTML, 401/403 envelope for JSON) already does
|
|
9
|
+
* the right thing. But framework code, middleware, and test harnesses
|
|
10
|
+
* occasionally need typed catches; that's what these classes are for.
|
|
11
|
+
*/
|
|
12
|
+
export class Run402AuthError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
status;
|
|
15
|
+
details;
|
|
16
|
+
suggestedFix;
|
|
17
|
+
docs;
|
|
18
|
+
constructor(opts) {
|
|
19
|
+
super(opts.message);
|
|
20
|
+
this.name = "Run402AuthError";
|
|
21
|
+
this.code = opts.code;
|
|
22
|
+
this.status = opts.status;
|
|
23
|
+
this.details = opts.details ?? {};
|
|
24
|
+
if (opts.suggestedFix)
|
|
25
|
+
this.suggestedFix = opts.suggestedFix;
|
|
26
|
+
if (opts.docs)
|
|
27
|
+
this.docs = opts.docs;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Subclass identifying the "anonymous on a protected route" case. The
|
|
31
|
+
* middleware decides whether to surface this as a 303 (HTML) or a 401
|
|
32
|
+
* envelope (JSON); user code never needs to make that choice. */
|
|
33
|
+
export class AuthRequiredError extends Run402AuthError {
|
|
34
|
+
constructor(opts = {}) {
|
|
35
|
+
super({
|
|
36
|
+
code: "R402_AUTH_REQUIRED",
|
|
37
|
+
status: 401,
|
|
38
|
+
message: "Authentication required.",
|
|
39
|
+
details: opts.returnTo ? { returnTo: opts.returnTo } : {},
|
|
40
|
+
suggestedFix: "Use: const user = await auth.requireUser()",
|
|
41
|
+
docs: "https://run402.com/errors/#R402_AUTH_REQUIRED",
|
|
42
|
+
});
|
|
43
|
+
this.name = "AuthRequiredError";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export class InsufficientRoleError extends Run402AuthError {
|
|
47
|
+
requiredRole;
|
|
48
|
+
constructor(requiredRole) {
|
|
49
|
+
super({
|
|
50
|
+
code: "R402_AUTH_INSUFFICIENT_ROLE",
|
|
51
|
+
status: 403,
|
|
52
|
+
message: `Authenticated user lacks required role: ${requiredRole}.`,
|
|
53
|
+
details: { required_role: requiredRole },
|
|
54
|
+
});
|
|
55
|
+
this.name = "InsufficientRoleError";
|
|
56
|
+
this.requiredRole = requiredRole;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export class InsufficientMembershipError extends Run402AuthError {
|
|
60
|
+
requiredMembership;
|
|
61
|
+
constructor(requiredMembership) {
|
|
62
|
+
super({
|
|
63
|
+
code: "R402_AUTH_INSUFFICIENT_MEMBERSHIP",
|
|
64
|
+
status: 403,
|
|
65
|
+
message: `Authenticated user lacks required membership: ${requiredMembership}.`,
|
|
66
|
+
details: { required_membership: requiredMembership },
|
|
67
|
+
});
|
|
68
|
+
this.name = "InsufficientMembershipError";
|
|
69
|
+
this.requiredMembership = requiredMembership;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export class FreshnessRequiredError extends Run402AuthError {
|
|
73
|
+
maxAge;
|
|
74
|
+
amr;
|
|
75
|
+
constructor(opts) {
|
|
76
|
+
super({
|
|
77
|
+
code: "R402_AUTH_FRESHNESS_REQUIRED",
|
|
78
|
+
status: 401,
|
|
79
|
+
message: `Fresh re-auth proof required within ${opts.maxAge} matching one of: ${opts.amr.join(", ")}.`,
|
|
80
|
+
details: { max_age: opts.maxAge, amr: opts.amr, returnTo: opts.returnTo ?? null },
|
|
81
|
+
});
|
|
82
|
+
this.name = "FreshnessRequiredError";
|
|
83
|
+
this.maxAge = opts.maxAge;
|
|
84
|
+
this.amr = opts.amr;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export class FetchAbsoluteUrlError extends Run402AuthError {
|
|
88
|
+
constructor(opts) {
|
|
89
|
+
super({
|
|
90
|
+
code: "R402_AUTH_FETCH_ABSOLUTE_URL",
|
|
91
|
+
status: 500,
|
|
92
|
+
message: `auth.fetch refused URL "${opts.attempted}": ${opts.reason}`,
|
|
93
|
+
details: { attempted_url: opts.attempted, reason: opts.reason },
|
|
94
|
+
suggestedFix: "auth.fetch accepts only same-origin paths. Cross-origin calls belong in your own service module.",
|
|
95
|
+
docs: "https://run402.com/errors/#R402_AUTH_FETCH_ABSOLUTE_URL",
|
|
96
|
+
});
|
|
97
|
+
this.name = "FetchAbsoluteUrlError";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export class PrerenderedError extends Run402AuthError {
|
|
101
|
+
constructor(opts) {
|
|
102
|
+
super({
|
|
103
|
+
code: "R402_AUTH_PRERENDERED",
|
|
104
|
+
status: 500,
|
|
105
|
+
message: `${opts.sdkFunction} cannot run in prerendered context.`,
|
|
106
|
+
details: { sdk_function: opts.sdkFunction },
|
|
107
|
+
suggestedFix: "Set `export const prerender = false` or use a server island.",
|
|
108
|
+
docs: "https://run402.com/errors/#R402_AUTH_PRERENDERED",
|
|
109
|
+
});
|
|
110
|
+
this.name = "PrerenderedError";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export class UnknownExportError extends Run402AuthError {
|
|
114
|
+
attemptedName;
|
|
115
|
+
canonicalName;
|
|
116
|
+
constructor(opts) {
|
|
117
|
+
super({
|
|
118
|
+
code: "R402_AUTH_UNKNOWN_EXPORT",
|
|
119
|
+
status: 500,
|
|
120
|
+
message: `Unknown SDK export: ${opts.attemptedName}. Use ${opts.canonicalName} instead.`,
|
|
121
|
+
details: {
|
|
122
|
+
attempted_name: opts.attemptedName,
|
|
123
|
+
canonical_name: opts.canonicalName,
|
|
124
|
+
import_line: 'import { auth } from "@run402/functions"',
|
|
125
|
+
},
|
|
126
|
+
suggestedFix: `Use: ${opts.canonicalName}`,
|
|
127
|
+
docs: "https://run402.com/errors/#R402_AUTH_UNKNOWN_EXPORT",
|
|
128
|
+
});
|
|
129
|
+
this.name = "UnknownExportError";
|
|
130
|
+
this.attemptedName = opts.attemptedName;
|
|
131
|
+
this.canonicalName = opts.canonicalName;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
export class SessionBridgeUnverifiedError extends Run402AuthError {
|
|
135
|
+
constructor(opts) {
|
|
136
|
+
super({
|
|
137
|
+
code: "R402_AUTH_SESSION_BRIDGE_UNVERIFIED",
|
|
138
|
+
status: 401,
|
|
139
|
+
message: `Session bridge refused unverified proof: ${opts.reason}`,
|
|
140
|
+
details: { reason: opts.reason },
|
|
141
|
+
suggestedFix: "Pass a verifiable proof to auth.sessions.createResponseFromIdentity({provider, subject, proof, amr, createUser?}).",
|
|
142
|
+
docs: "https://run402.com/errors/#R402_AUTH_SESSION_BRIDGE_UNVERIFIED",
|
|
143
|
+
});
|
|
144
|
+
this.name = "SessionBridgeUnverifiedError";
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export class IdentityLinkConflictError extends Run402AuthError {
|
|
148
|
+
constructor(opts) {
|
|
149
|
+
super({
|
|
150
|
+
code: "R402_AUTH_IDENTITY_LINK_CONFLICT",
|
|
151
|
+
status: 409,
|
|
152
|
+
message: `Identity (${opts.provider}, ${opts.subject}) is already linked to another user.`,
|
|
153
|
+
details: { provider: opts.provider, subject: opts.subject },
|
|
154
|
+
});
|
|
155
|
+
this.name = "IdentityLinkConflictError";
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export class UnknownIdentityError extends Run402AuthError {
|
|
159
|
+
constructor(opts) {
|
|
160
|
+
super({
|
|
161
|
+
code: "R402_AUTH_UNKNOWN_IDENTITY",
|
|
162
|
+
status: 401,
|
|
163
|
+
message: `Identity (${opts.provider}, ${opts.subject}) not found.`,
|
|
164
|
+
details: { provider: opts.provider, subject: opts.subject },
|
|
165
|
+
suggestedFix: "Pass `createUser: true` to auth.sessions.createResponseFromIdentity if first-sign-in should create the user.",
|
|
166
|
+
});
|
|
167
|
+
this.name = "UnknownIdentityError";
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** The canonical "your own credential check failed" error. Thrown via the
|
|
171
|
+
* `auth.invalidCredentials()` FUNCTION (not `new auth.InvalidCredentialsError()`)
|
|
172
|
+
* per D9 — agents fumble the constructor+import; `throw auth.invalidCredentials()`
|
|
173
|
+
* is one call and renders the canonical `R402_AUTH_INVALID_CREDENTIALS` envelope
|
|
174
|
+
* (distinct from `R402_AUTH_MAGIC_LINK_INVALID`). */
|
|
175
|
+
export class InvalidCredentialsError extends Run402AuthError {
|
|
176
|
+
constructor() {
|
|
177
|
+
super({
|
|
178
|
+
code: "R402_AUTH_INVALID_CREDENTIALS",
|
|
179
|
+
status: 401,
|
|
180
|
+
message: "Invalid credentials.",
|
|
181
|
+
details: {},
|
|
182
|
+
suggestedFix: 'After your own credential check fails, use: throw auth.invalidCredentials()',
|
|
183
|
+
docs: "https://run402.com/errors/#R402_AUTH_INVALID_CREDENTIALS",
|
|
184
|
+
});
|
|
185
|
+
this.name = "InvalidCredentialsError";
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Rejects a tenant-assertion mint whose `user` lacks a stable `id` (e.g. a
|
|
189
|
+
* bare email). The `fix` shows the required `{ tenant, user: { id, email, ... },
|
|
190
|
+
* method }` shape. SDK-side fast-feedback twin of the gateway's
|
|
191
|
+
* `R402_AUTH_TENANT_SUBJECT_INVALID` envelope. */
|
|
192
|
+
export class TenantSubjectInvalidError extends Run402AuthError {
|
|
193
|
+
constructor(opts) {
|
|
194
|
+
super({
|
|
195
|
+
code: "R402_AUTH_TENANT_SUBJECT_INVALID",
|
|
196
|
+
status: 400,
|
|
197
|
+
message: `Tenant assertion subject invalid: ${opts.reason}`,
|
|
198
|
+
details: { reason: opts.reason },
|
|
199
|
+
suggestedFix: 'Pass a stable id: auth.sessions.createResponseFromTenantAssertion({ tenant, user: { id, email, emailVerified }, method: "password" })',
|
|
200
|
+
docs: "https://run402.com/errors/#R402_AUTH_TENANT_SUBJECT_INVALID",
|
|
201
|
+
});
|
|
202
|
+
this.name = "TenantSubjectInvalidError";
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `auth.*` — the sole server-side auth namespace.
|
|
3
|
+
*
|
|
4
|
+
* The single import line for any consumer:
|
|
5
|
+
*
|
|
6
|
+
* import { auth } from "@run402/functions";
|
|
7
|
+
*
|
|
8
|
+
* Surface (deliberately small):
|
|
9
|
+
*
|
|
10
|
+
* auth.user() → Actor | null
|
|
11
|
+
* auth.requireUser() → Actor (throws / 303 otherwise)
|
|
12
|
+
* auth.requireRole(role) → { user, role }
|
|
13
|
+
* auth.requireMembership(membership) → { user, membership }
|
|
14
|
+
* auth.requireFresh({ maxAge, amr? }) → void (throws / 303 otherwise)
|
|
15
|
+
* auth.identities.link({ ... }) → void
|
|
16
|
+
* auth.fetch(input, init?) → Response (same-origin only)
|
|
17
|
+
* auth.csrfToken() → string
|
|
18
|
+
* auth.csrfField() → "<input type=hidden ...>"
|
|
19
|
+
* auth.sessions.createResponseFromIdentity({ ... }) → Response
|
|
20
|
+
* auth.sessions.createResponseFromTenantAssertion({ tenant, user, method }) → Response
|
|
21
|
+
* auth.sessions.endResponse() → Response
|
|
22
|
+
* auth.invalidCredentials() → InvalidCredentialsError (throw it)
|
|
23
|
+
*
|
|
24
|
+
* Behaviour notes baked into the helpers:
|
|
25
|
+
* - Calling any helper taints the cache (the response now depends on
|
|
26
|
+
* per-request actor state). The taint is monotonic — once set, the
|
|
27
|
+
* SSR cache layer treats the response as non-cacheable until the
|
|
28
|
+
* request completes.
|
|
29
|
+
* - HTML-vs-JSON failure decisions are made by the gateway middleware
|
|
30
|
+
* (303 redirect for HTML, 401/403 envelope for JSON). The SDK throws
|
|
31
|
+
* a typed Error subclass; framework code OR the gateway translates.
|
|
32
|
+
* - `requireRole` / `requireMembership` always read fresh server-side
|
|
33
|
+
* grant data — no positive cache (matches D8 + the "instant revocation"
|
|
34
|
+
* contract). For now we route via `getRole` which the gateway sets
|
|
35
|
+
* at the routed-function envelope; once the v1.60 grants table lands,
|
|
36
|
+
* gate helpers will JOIN against it inside the same request.
|
|
37
|
+
* - `requireFresh` consults the per-method `amr_times` on the Actor —
|
|
38
|
+
* a recent password proof does NOT satisfy `{amr: ["passkey"]}`.
|
|
39
|
+
*
|
|
40
|
+
* @see openspec/changes/auth-aware-ssr/specs/auth-sdk-namespace/spec.md
|
|
41
|
+
*/
|
|
42
|
+
import { InvalidCredentialsError } from "./errors.js";
|
|
43
|
+
import type { Actor, CreateResponseFromIdentityOptions, CreateResponseFromTenantAssertionOptions, IdentityLinkOptions } from "./types.js";
|
|
44
|
+
interface RequireFreshOptions {
|
|
45
|
+
/** Human-friendly window expression. Accepted forms: `"10m"`, `"1h"`,
|
|
46
|
+
* `"5m30s"`, integer seconds (`"600"`). Anything that fails to parse
|
|
47
|
+
* is treated as 0s (immediate freshness required). */
|
|
48
|
+
maxAge: string;
|
|
49
|
+
/** Names of AMR methods one of which must have been verified within
|
|
50
|
+
* `maxAge`. When omitted, any flat `auth_time` proof within `maxAge`
|
|
51
|
+
* satisfies. */
|
|
52
|
+
amr?: string[];
|
|
53
|
+
}
|
|
54
|
+
/** Header on the function's RETURNED Response that the gateway's routed-invoke
|
|
55
|
+
* post-processor materializes into a host-bound `Set-Cookie` — AFTER it
|
|
56
|
+
* checks the INVOKED function's declared `auth.sessionMint` capability
|
|
57
|
+
* (server-side; service-key presence is NOT sufficient). The gateway always
|
|
58
|
+
* strips this header before the client sees it. Kept in sync with the
|
|
59
|
+
* gateway constant of the same name. */
|
|
60
|
+
export declare const MINT_DIRECTIVE_HEADER = "x-run402-mint-directive";
|
|
61
|
+
interface AuthNamespace {
|
|
62
|
+
user(): Promise<Actor | null>;
|
|
63
|
+
requireUser(): Promise<Actor>;
|
|
64
|
+
requireRole<const R extends string>(role: R): Promise<{
|
|
65
|
+
user: Actor;
|
|
66
|
+
role: R;
|
|
67
|
+
}>;
|
|
68
|
+
requireMembership<const M extends string>(membership: M): Promise<{
|
|
69
|
+
user: Actor;
|
|
70
|
+
membership: M;
|
|
71
|
+
}>;
|
|
72
|
+
requireFresh(opts: RequireFreshOptions): Promise<void>;
|
|
73
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
74
|
+
csrfToken(): string;
|
|
75
|
+
csrfField(): string;
|
|
76
|
+
/** Canonical invalid-credentials failure for the tenant-owned credential
|
|
77
|
+
* case. A function (not a constructor): `throw auth.invalidCredentials()`. */
|
|
78
|
+
invalidCredentials(): InvalidCredentialsError;
|
|
79
|
+
identities: {
|
|
80
|
+
link(opts: IdentityLinkOptions): Promise<void>;
|
|
81
|
+
};
|
|
82
|
+
sessions: {
|
|
83
|
+
createResponseFromIdentity(opts: CreateResponseFromIdentityOptions): Promise<Response>;
|
|
84
|
+
createResponseFromTenantAssertion(opts: CreateResponseFromTenantAssertionOptions): Promise<Response>;
|
|
85
|
+
endResponse(): Promise<Response>;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Hallucinated-name proxy. Property access for a name not in
|
|
89
|
+
* `baseAuth` throws `R402_AUTH_UNKNOWN_EXPORT` with the canonical
|
|
90
|
+
* replacement. Hot-path access (existing keys) returns the actual
|
|
91
|
+
* helper — proxy overhead is one Reflect.has + Reflect.get. */
|
|
92
|
+
export declare const auth: AuthNamespace;
|
|
93
|
+
/** Throwing-sentinel exports for the top hallucinated *bare* names.
|
|
94
|
+
* ESM `import { getUser } from "@run402/functions"` can be intercepted
|
|
95
|
+
* only by a real export — so we ship these as exported throwing
|
|
96
|
+
* functions. They're marked `@deprecated` in the type JSDoc; the SDK
|
|
97
|
+
* proxy + lint registry + `run402 doctor` scan all flag the import
|
|
98
|
+
* before runtime if the user is running the tooling.
|
|
99
|
+
*
|
|
100
|
+
* Excluded from public docs and AGENTS.md per the spec.
|
|
101
|
+
*/
|
|
102
|
+
/** @deprecated Use `auth.user()` or `auth.requireUser()`. */
|
|
103
|
+
export declare function getSession(): never;
|
|
104
|
+
/** @deprecated Use `auth.user()`. */
|
|
105
|
+
export declare function currentUser(): never;
|
|
106
|
+
/** @deprecated Use `auth.user()`. */
|
|
107
|
+
export declare function getCurrentUser(): never;
|
|
108
|
+
/** @deprecated Use `auth.user()`. */
|
|
109
|
+
export declare function getServerSession(): never;
|
|
110
|
+
export type { Actor, IdentityProof, TenantUser, CreateResponseFromTenantAssertionOptions, } from "./types.js";
|
|
111
|
+
export { AuthRequiredError, InsufficientRoleError, InsufficientMembershipError, FreshnessRequiredError, FetchAbsoluteUrlError, PrerenderedError, UnknownExportError, SessionBridgeUnverifiedError, IdentityLinkConflictError, UnknownIdentityError, InvalidCredentialsError, TenantSubjectInvalidError, Run402AuthError, } from "./errors.js";
|
|
112
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAUH,OAAO,EAML,uBAAuB,EAIxB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,KAAK,EACL,iCAAiC,EACjC,wCAAwC,EACxC,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAsJpB,UAAU,mBAAmB;IAC3B;;2DAEuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf;;qBAEiB;IACjB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AA8JD;;;;;yCAKyC;AACzC,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AA2K/D,UAAU,aAAa;IACrB,IAAI,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC9B,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,WAAW,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAChF,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EACtC,UAAU,EAAE,CAAC,GACZ,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,UAAU,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC3C,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,SAAS,IAAI,MAAM,CAAC;IACpB,SAAS,IAAI,MAAM,CAAC;IACpB;mFAC+E;IAC/E,kBAAkB,IAAI,uBAAuB,CAAC;IAC9C,UAAU,EAAE;QACV,IAAI,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAChD,CAAC;IACF,QAAQ,EAAE;QACR,0BAA0B,CAAC,IAAI,EAAE,iCAAiC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvF,iCAAiC,CAC/B,IAAI,EAAE,wCAAwC,GAC7C,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;KAClC,CAAC;CACH;AAoDD;;;gEAGgE;AAChE,eAAO,MAAM,IAAI,EAAE,aAiBjB,CAAC;AAEH;;;;;;;;GAQG;AAEH,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,KAAK,CAElC;AAED,qCAAqC;AACrC,wBAAgB,WAAW,IAAI,KAAK,CAEnC;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,KAAK,CAEtC;AAED,qCAAqC;AACrC,wBAAgB,gBAAgB,IAAI,KAAK,CAKxC;AA8BD,YAAY,EACV,KAAK,EACL,aAAa,EACb,UAAU,EACV,wCAAwC,GACzC,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,4BAA4B,EAC5B,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,eAAe,GAChB,MAAM,aAAa,CAAC"}
|