@seamless-auth/core 0.5.1-beta.20260523225720 → 0.5.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/README.md +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/scopedRoles.d.ts +3 -0
- package/dist/scopedRoles.d.ts.map +1 -0
- package/dist/scopedRoles.js +39 -0
- package/dist/scopedRoles.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,6 +88,7 @@ Key exports include:
|
|
|
88
88
|
- `refreshAccessToken(...)` – rotates expired access sessions
|
|
89
89
|
- `verifyCookieJwt(...)` – verifies signed cookie payloads
|
|
90
90
|
- `createServiceToken(...)` – creates short-lived M2M assertions
|
|
91
|
+
- `hasScopedRole(...)` – checks scoped role grants such as `admin:read`
|
|
91
92
|
- `listOAuthProvidersHandler(...)` – retrieves public OAuth provider metadata
|
|
92
93
|
- `startOAuthLoginHandler(...)` – starts an OAuth authorization-code login
|
|
93
94
|
- `finishOAuthLoginHandler(...)` – finishes OAuth login and returns cookie instructions
|
|
@@ -172,6 +173,23 @@ provider identity linking. Core and adapter code never store provider access tok
|
|
|
172
173
|
|
|
173
174
|
---
|
|
174
175
|
|
|
176
|
+
## Scoped Roles
|
|
177
|
+
|
|
178
|
+
Core exports `hasScopedRole` and `roleGrantsAccess` for framework adapters and custom servers that
|
|
179
|
+
need the same authorization semantics as `@seamless-auth/express`.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { hasScopedRole } from "@seamless-auth/core";
|
|
183
|
+
|
|
184
|
+
hasScopedRole(["admin:write"], "admin:read"); // true
|
|
185
|
+
hasScopedRole(["admin:read"], "admin:write"); // false
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Plain roles remain backwards compatible. `admin` grants `admin:read` and `admin:write`, while
|
|
189
|
+
`admin:read` does not satisfy a plain `admin` check.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
175
193
|
## Testing
|
|
176
194
|
|
|
177
195
|
All logic in this package is tested against compiled output (`dist/`),
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./verifyCookieJwt.js";
|
|
|
5
5
|
export * from "./refreshAccessToken.js";
|
|
6
6
|
export * from "./getSeamlessUser.js";
|
|
7
7
|
export * from "./createServiceToken.js";
|
|
8
|
+
export * from "./scopedRoles.js";
|
|
8
9
|
export * from "./handlers/login.js";
|
|
9
10
|
export * from "./handlers/finishLogin.js";
|
|
10
11
|
export * from "./handlers/register.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AAEjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./verifyCookieJwt.js";
|
|
|
5
5
|
export * from "./refreshAccessToken.js";
|
|
6
6
|
export * from "./getSeamlessUser.js";
|
|
7
7
|
export * from "./createServiceToken.js";
|
|
8
|
+
export * from "./scopedRoles.js";
|
|
8
9
|
export * from "./handlers/login.js";
|
|
9
10
|
export * from "./handlers/finishLogin.js";
|
|
10
11
|
export * from "./handlers/register.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AAEjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,yCAAyC,CAAC;AACxD,cAAc,6BAA6B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopedRoles.d.ts","sourceRoot":"","sources":["../src/scopedRoles.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAsCnF;AAED,wBAAgB,aAAa,CAC3B,YAAY,EAAE,OAAO,EACrB,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,GAC/B,OAAO,CAaT"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function roleGrantsAccess(grantedRole, requiredRole) {
|
|
2
|
+
const granted = grantedRole.trim();
|
|
3
|
+
const required = requiredRole.trim();
|
|
4
|
+
if (!granted || !required) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (granted === required) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
if (granted.endsWith(":*")) {
|
|
11
|
+
const prefix = granted.slice(0, -2);
|
|
12
|
+
return required === prefix || required.startsWith(`${prefix}:`);
|
|
13
|
+
}
|
|
14
|
+
if (!required.includes(":")) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
if (!granted.includes(":")) {
|
|
18
|
+
return required.startsWith(`${granted}:`);
|
|
19
|
+
}
|
|
20
|
+
const grantedParts = granted.split(":");
|
|
21
|
+
const requiredParts = required.split(":");
|
|
22
|
+
const grantedAction = grantedParts.at(-1);
|
|
23
|
+
const requiredAction = requiredParts.at(-1);
|
|
24
|
+
const grantedPrefix = grantedParts.slice(0, -1);
|
|
25
|
+
const requiredPrefix = requiredParts.slice(0, -1);
|
|
26
|
+
return (grantedAction === "write" &&
|
|
27
|
+
requiredAction === "read" &&
|
|
28
|
+
grantedPrefix.length === requiredPrefix.length &&
|
|
29
|
+
grantedPrefix.every((part, index) => part === requiredPrefix[index]));
|
|
30
|
+
}
|
|
31
|
+
export function hasScopedRole(grantedRoles, requiredRoles) {
|
|
32
|
+
if (!Array.isArray(grantedRoles)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const granted = grantedRoles.filter((role) => typeof role === "string");
|
|
36
|
+
const required = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
|
|
37
|
+
return required.some((requiredRole) => granted.some((grantedRole) => roleGrantsAccess(grantedRole, requiredRole)));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=scopedRoles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopedRoles.js","sourceRoot":"","sources":["../src/scopedRoles.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,YAAoB;IACxE,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IAErC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,aAAa,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAElD,OAAO,CACL,aAAa,KAAK,OAAO;QACzB,cAAc,KAAK,MAAM;QACzB,aAAa,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM;QAC9C,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC,CACrE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,YAAqB,EACrB,aAAgC;IAEhC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CACjC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CACnD,CAAC;IACF,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAEhF,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CACpC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED