@reckona/mreact-auth 0.0.1
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 +57 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +202 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tatsuo Kaniwa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# @reckona/mreact-auth
|
|
2
|
+
|
|
3
|
+
`@reckona/mreact-auth` provides session and authorization helpers for the mreact
|
|
4
|
+
app router. It layers role and permission guards plus client claims hand-off on
|
|
5
|
+
top of the router's cookie/session integration points.
|
|
6
|
+
|
|
7
|
+
## Basic Usage
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { configureAuth, getCurrentSession, requireRole } from "@reckona/mreact-auth";
|
|
11
|
+
import { sessionStore } from "./session-store";
|
|
12
|
+
|
|
13
|
+
configureAuth({
|
|
14
|
+
redirectTo: "/login",
|
|
15
|
+
forbiddenTo: "/forbidden",
|
|
16
|
+
serializeClaims(data) {
|
|
17
|
+
if (typeof data !== "object" || data === null) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
roles: Array.isArray(data.roles)
|
|
23
|
+
? data.roles.filter((role): role is string => typeof role === "string")
|
|
24
|
+
: undefined,
|
|
25
|
+
userId: "userId" in data ? String(data.userId) : undefined,
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export async function loader({ request }) {
|
|
31
|
+
const session = await getCurrentSession(request, sessionStore);
|
|
32
|
+
await requireRole(request, sessionStore, ["admin", "editor"]);
|
|
33
|
+
return { user: session?.claims };
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Core APIs
|
|
38
|
+
|
|
39
|
+
- `configureAuth()` sets app-wide redirect and forbidden defaults.
|
|
40
|
+
- `createMemorySessionStore()`, `createSession()`, `getSession()`,
|
|
41
|
+
`destroySession()`, and `rotateSession()` are the canonical session helper
|
|
42
|
+
imports for application code.
|
|
43
|
+
- `getCurrentSession()` returns the current request session.
|
|
44
|
+
- `requireRole()` and `requirePermission()` redirect or reject when the policy is not met.
|
|
45
|
+
- `tryRequireRole()` and `tryRequirePermission()` return a boolean policy result.
|
|
46
|
+
- `getSessionClaims()` reads session claims on both server and client hand-off paths.
|
|
47
|
+
|
|
48
|
+
## Router Integration
|
|
49
|
+
|
|
50
|
+
Set `export const auth = "include-claims"` in a page module when the router should
|
|
51
|
+
embed session claims into the HTML response. Client components can then call
|
|
52
|
+
`getSessionClaims()` without passing claims through every page prop.
|
|
53
|
+
|
|
54
|
+
By default, the hand-off includes only authorization claims: `roles` and
|
|
55
|
+
`permissions`. Use `configureAuth({ serializeClaims })` to expose additional
|
|
56
|
+
browser-safe fields, such as a public user id. Do not return server-only values
|
|
57
|
+
such as refresh tokens or provider secrets from the serializer.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createMemorySessionStore, createSession, destroySession, getSession, rotateSession, type SessionCookieOptions, type SessionRecord, type SessionStore } from "@reckona/mreact-router/internal/session";
|
|
2
|
+
export { createMemorySessionStore, createSession, destroySession, getSession, rotateSession };
|
|
3
|
+
export type { SessionCookieOptions, SessionRecord, SessionStore };
|
|
4
|
+
export declare const __MREACT_AUTH_SESSION_SCRIPT_ID = "__mreact_auth_session";
|
|
5
|
+
export interface AuthSessionClaims {
|
|
6
|
+
[claim: string]: unknown;
|
|
7
|
+
permissions?: readonly string[] | undefined;
|
|
8
|
+
roles?: readonly string[] | undefined;
|
|
9
|
+
}
|
|
10
|
+
export interface AuthGuardOptions {
|
|
11
|
+
forbiddenTo?: string | undefined;
|
|
12
|
+
mode?: AuthRequirementMode | undefined;
|
|
13
|
+
redirectTo?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
export interface AuthConfig {
|
|
16
|
+
forbiddenTo?: string | undefined;
|
|
17
|
+
redirectTo?: string | undefined;
|
|
18
|
+
serializeClaims?: AuthClaimsSerializer | undefined;
|
|
19
|
+
}
|
|
20
|
+
export type AuthRequirement = string | readonly string[];
|
|
21
|
+
export type AuthRequirementMode = "all" | "any";
|
|
22
|
+
export type AuthClaimsSerializer = (data: unknown) => AuthSessionClaims | undefined;
|
|
23
|
+
export interface AuthorizationPolicy {
|
|
24
|
+
permissions?: readonly string[] | undefined;
|
|
25
|
+
roles?: readonly string[] | undefined;
|
|
26
|
+
}
|
|
27
|
+
export type AuthorizationResult = {
|
|
28
|
+
authorized: true;
|
|
29
|
+
} | {
|
|
30
|
+
authorized: false;
|
|
31
|
+
reason: "missing-permission" | "missing-role";
|
|
32
|
+
};
|
|
33
|
+
export type TryAuthResult<TData> = {
|
|
34
|
+
authorized: true;
|
|
35
|
+
session: SessionRecord<TData>;
|
|
36
|
+
} | {
|
|
37
|
+
authorized: false;
|
|
38
|
+
reason: "missing-permission" | "missing-role" | "missing-session";
|
|
39
|
+
};
|
|
40
|
+
export declare function configureAuth(config: AuthConfig): void;
|
|
41
|
+
export declare function getCurrentSession<TData>(request: Request, store: SessionStore<TData>, options?: SessionCookieOptions): Promise<SessionRecord<TData> | undefined>;
|
|
42
|
+
export declare function requireSession<TData>(request: Request, store: SessionStore<TData>, options?: AuthGuardOptions): Promise<SessionRecord<TData>>;
|
|
43
|
+
export declare function requireRole<TData extends AuthSessionClaims>(request: Request, store: SessionStore<TData>, role: AuthRequirement, options?: AuthGuardOptions): Promise<SessionRecord<TData>>;
|
|
44
|
+
export declare function requirePermission<TData extends AuthSessionClaims>(request: Request, store: SessionStore<TData>, permission: AuthRequirement, options?: AuthGuardOptions): Promise<SessionRecord<TData>>;
|
|
45
|
+
export declare function tryRequireRole<TData extends AuthSessionClaims>(request: Request, store: SessionStore<TData>, role: AuthRequirement, options?: Pick<AuthGuardOptions, "mode">): Promise<TryAuthResult<TData>>;
|
|
46
|
+
export declare function tryRequirePermission<TData extends AuthSessionClaims>(request: Request, store: SessionStore<TData>, permission: AuthRequirement, options?: Pick<AuthGuardOptions, "mode">): Promise<TryAuthResult<TData>>;
|
|
47
|
+
export declare function authorizeSession<TData extends AuthSessionClaims>(data: TData, policy: AuthorizationPolicy): AuthorizationResult;
|
|
48
|
+
export declare function getSessionClaims<TData extends AuthSessionClaims = AuthSessionClaims>(): TData | undefined;
|
|
49
|
+
export declare function __resetAuthForTesting(): void;
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { createMemorySessionStore, createSession, destroySession, getSession, rotateSession, } from "@reckona/mreact-router/internal/session";
|
|
2
|
+
import { getGlobalRuntimeState } from "@reckona/mreact-reactive-core/internal";
|
|
3
|
+
import { redirect } from "@reckona/mreact-router";
|
|
4
|
+
export { createMemorySessionStore, createSession, destroySession, getSession, rotateSession };
|
|
5
|
+
export const __MREACT_AUTH_SESSION_SCRIPT_ID = "__mreact_auth_session";
|
|
6
|
+
const authRuntimeStateKey = "__mreactAuthRuntimeState";
|
|
7
|
+
let authConfig = {
|
|
8
|
+
forbiddenTo: "/forbidden",
|
|
9
|
+
redirectTo: "/login",
|
|
10
|
+
serializeClaims: defaultSerializeSessionClaims,
|
|
11
|
+
};
|
|
12
|
+
export function configureAuth(config) {
|
|
13
|
+
authConfig = {
|
|
14
|
+
forbiddenTo: config.forbiddenTo ?? authConfig.forbiddenTo,
|
|
15
|
+
redirectTo: config.redirectTo ?? authConfig.redirectTo,
|
|
16
|
+
serializeClaims: config.serializeClaims ?? authConfig.serializeClaims,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export async function getCurrentSession(request, store, options = {}) {
|
|
20
|
+
const session = await getSession(request, store, options);
|
|
21
|
+
setSessionClaims(session?.data);
|
|
22
|
+
return session;
|
|
23
|
+
}
|
|
24
|
+
export async function requireSession(request, store, options = {}) {
|
|
25
|
+
const session = await getCurrentSession(request, store);
|
|
26
|
+
if (session === undefined) {
|
|
27
|
+
redirect(authRedirectTo(options), { status: 303 });
|
|
28
|
+
}
|
|
29
|
+
return session;
|
|
30
|
+
}
|
|
31
|
+
export async function requireRole(request, store, role, options = {}) {
|
|
32
|
+
const session = await requireSession(request, store, options);
|
|
33
|
+
const result = authorizeRequirement(session.data.roles, role, "missing-role", options.mode);
|
|
34
|
+
if (!result.authorized) {
|
|
35
|
+
redirect(authForbiddenTo(options), { status: 303 });
|
|
36
|
+
}
|
|
37
|
+
return session;
|
|
38
|
+
}
|
|
39
|
+
export async function requirePermission(request, store, permission, options = {}) {
|
|
40
|
+
const session = await requireSession(request, store, options);
|
|
41
|
+
const result = authorizeRequirement(session.data.permissions, permission, "missing-permission", options.mode);
|
|
42
|
+
if (!result.authorized) {
|
|
43
|
+
redirect(authForbiddenTo(options), { status: 303 });
|
|
44
|
+
}
|
|
45
|
+
return session;
|
|
46
|
+
}
|
|
47
|
+
export async function tryRequireRole(request, store, role, options = {}) {
|
|
48
|
+
const session = await getCurrentSession(request, store);
|
|
49
|
+
if (session === undefined) {
|
|
50
|
+
return { authorized: false, reason: "missing-session" };
|
|
51
|
+
}
|
|
52
|
+
const result = authorizeRequirement(session.data.roles, role, "missing-role", options.mode);
|
|
53
|
+
return result.authorized ? { authorized: true, session } : result;
|
|
54
|
+
}
|
|
55
|
+
export async function tryRequirePermission(request, store, permission, options = {}) {
|
|
56
|
+
const session = await getCurrentSession(request, store);
|
|
57
|
+
if (session === undefined) {
|
|
58
|
+
return { authorized: false, reason: "missing-session" };
|
|
59
|
+
}
|
|
60
|
+
const result = authorizeRequirement(session.data.permissions, permission, "missing-permission", options.mode);
|
|
61
|
+
return result.authorized ? { authorized: true, session } : result;
|
|
62
|
+
}
|
|
63
|
+
export function authorizeSession(data, policy) {
|
|
64
|
+
if (!hasAll(data.roles, policy.roles)) {
|
|
65
|
+
return {
|
|
66
|
+
authorized: false,
|
|
67
|
+
reason: "missing-role",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (!hasAll(data.permissions, policy.permissions)) {
|
|
71
|
+
return {
|
|
72
|
+
authorized: false,
|
|
73
|
+
reason: "missing-permission",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { authorized: true };
|
|
77
|
+
}
|
|
78
|
+
export function getSessionClaims() {
|
|
79
|
+
const state = authRuntimeState();
|
|
80
|
+
const requestClaims = state.storage?.getStore()?.claims;
|
|
81
|
+
if (requestClaims !== undefined) {
|
|
82
|
+
return requestClaims;
|
|
83
|
+
}
|
|
84
|
+
if (typeof document === "undefined") {
|
|
85
|
+
return state.currentClaims;
|
|
86
|
+
}
|
|
87
|
+
if (state.browserClaims === undefined) {
|
|
88
|
+
state.browserClaims = readClaimsFromDocument();
|
|
89
|
+
}
|
|
90
|
+
return state.browserClaims;
|
|
91
|
+
}
|
|
92
|
+
export function __resetAuthForTesting() {
|
|
93
|
+
authConfig = {
|
|
94
|
+
forbiddenTo: "/forbidden",
|
|
95
|
+
redirectTo: "/login",
|
|
96
|
+
serializeClaims: defaultSerializeSessionClaims,
|
|
97
|
+
};
|
|
98
|
+
const state = authRuntimeState();
|
|
99
|
+
state.browserClaims = undefined;
|
|
100
|
+
state.currentClaims = undefined;
|
|
101
|
+
const requestState = state.storage?.getStore();
|
|
102
|
+
if (requestState !== undefined) {
|
|
103
|
+
requestState.claims = undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function authorizeRequirement(available, requirement, reason, mode = "any") {
|
|
107
|
+
const required = Array.isArray(requirement) ? requirement : [requirement];
|
|
108
|
+
const authorized = mode === "all" ? hasAll(available, required) : hasAny(available, required);
|
|
109
|
+
return authorized ? { authorized: true } : { authorized: false, reason };
|
|
110
|
+
}
|
|
111
|
+
function authRedirectTo(options) {
|
|
112
|
+
return options.redirectTo ?? authConfig.redirectTo;
|
|
113
|
+
}
|
|
114
|
+
function authForbiddenTo(options) {
|
|
115
|
+
return options.forbiddenTo ?? authConfig.forbiddenTo;
|
|
116
|
+
}
|
|
117
|
+
function hasAll(available, required) {
|
|
118
|
+
if (required === undefined || required.length === 0) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
if (available === undefined || available.length === 0) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const values = new Set(available);
|
|
125
|
+
return required.every((value) => values.has(value));
|
|
126
|
+
}
|
|
127
|
+
function hasAny(available, required) {
|
|
128
|
+
if (required === undefined || required.length === 0) {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
if (available === undefined || available.length === 0) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
const values = new Set(available);
|
|
135
|
+
return required.some((value) => values.has(value));
|
|
136
|
+
}
|
|
137
|
+
function setSessionClaims(data) {
|
|
138
|
+
const claims = normalizeSessionClaims(authConfig.serializeClaims(data));
|
|
139
|
+
const state = authRuntimeState();
|
|
140
|
+
const requestState = state.storage?.getStore();
|
|
141
|
+
if (requestState !== undefined) {
|
|
142
|
+
requestState.claims = claims;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
state.currentClaims = claims;
|
|
146
|
+
}
|
|
147
|
+
function readClaimsFromDocument() {
|
|
148
|
+
const node = document.getElementById(__MREACT_AUTH_SESSION_SCRIPT_ID);
|
|
149
|
+
if (node?.textContent === undefined || node.textContent === "") {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const parsed = JSON.parse(node.textContent);
|
|
154
|
+
return normalizeSessionClaims(parsed);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function defaultSerializeSessionClaims(data) {
|
|
161
|
+
const claims = normalizeSessionClaims(data);
|
|
162
|
+
if (claims === undefined) {
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
const safeClaims = {};
|
|
166
|
+
if (claims.permissions !== undefined) {
|
|
167
|
+
safeClaims.permissions = claims.permissions;
|
|
168
|
+
}
|
|
169
|
+
if (claims.roles !== undefined) {
|
|
170
|
+
safeClaims.roles = claims.roles;
|
|
171
|
+
}
|
|
172
|
+
return Object.keys(safeClaims).length === 0 ? undefined : safeClaims;
|
|
173
|
+
}
|
|
174
|
+
function normalizeSessionClaims(value) {
|
|
175
|
+
if (typeof value !== "object" || value === null) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
const claims = value;
|
|
179
|
+
const roles = normalizeStringArray(claims.roles);
|
|
180
|
+
const permissions = normalizeStringArray(claims.permissions);
|
|
181
|
+
if ((claims.roles !== undefined && roles === undefined) ||
|
|
182
|
+
(claims.permissions !== undefined && permissions === undefined)) {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
...claims,
|
|
187
|
+
...(permissions === undefined ? {} : { permissions }),
|
|
188
|
+
...(roles === undefined ? {} : { roles }),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function normalizeStringArray(value) {
|
|
192
|
+
if (value === undefined) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string")
|
|
196
|
+
? value
|
|
197
|
+
: undefined;
|
|
198
|
+
}
|
|
199
|
+
function authRuntimeState() {
|
|
200
|
+
return getGlobalRuntimeState(authRuntimeStateKey, () => ({}));
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reckona/mreact-auth",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Session and authorization helpers for mreact app router applications.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"auth",
|
|
7
|
+
"authorization",
|
|
8
|
+
"jsx",
|
|
9
|
+
"mreact",
|
|
10
|
+
"router",
|
|
11
|
+
"sessions",
|
|
12
|
+
"typescript"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/t-k/mreact/tree/main/packages/auth#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/t-k/mreact/issues"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/t-k/mreact.git",
|
|
22
|
+
"directory": "packages/auth"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist/**/*.js",
|
|
26
|
+
"dist/**/*.js.map",
|
|
27
|
+
"dist/**/*.d.ts",
|
|
28
|
+
"dist/**/*.d.ts.map"
|
|
29
|
+
],
|
|
30
|
+
"type": "module",
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@reckona/mreact-reactive-core": "0.0.1",
|
|
44
|
+
"@reckona/mreact-router": "0.0.1"
|
|
45
|
+
}
|
|
46
|
+
}
|