@seamless-auth/express 0.0.2-beta.1 → 0.0.2-beta.10

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.
Files changed (40) hide show
  1. package/LICENSE +79 -0
  2. package/LICENSE.md +26 -0
  3. package/README.md +99 -123
  4. package/dist/index.d.ts +190 -7
  5. package/dist/index.js +501 -5
  6. package/package.json +31 -14
  7. package/dist/createServer.d.ts +0 -48
  8. package/dist/createServer.d.ts.map +0 -1
  9. package/dist/createServer.js +0 -164
  10. package/dist/index.d.ts.map +0 -1
  11. package/dist/internal/authFetch.d.ts +0 -9
  12. package/dist/internal/authFetch.d.ts.map +0 -1
  13. package/dist/internal/authFetch.js +0 -37
  14. package/dist/internal/cookie.d.ts +0 -11
  15. package/dist/internal/cookie.d.ts.map +0 -1
  16. package/dist/internal/cookie.js +0 -28
  17. package/dist/internal/getSeamlessUser.d.ts +0 -51
  18. package/dist/internal/getSeamlessUser.d.ts.map +0 -1
  19. package/dist/internal/getSeamlessUser.js +0 -72
  20. package/dist/internal/refreshAccessToken.d.ts +0 -10
  21. package/dist/internal/refreshAccessToken.d.ts.map +0 -1
  22. package/dist/internal/refreshAccessToken.js +0 -44
  23. package/dist/internal/verifyCookieJwt.d.ts +0 -2
  24. package/dist/internal/verifyCookieJwt.d.ts.map +0 -1
  25. package/dist/internal/verifyCookieJwt.js +0 -13
  26. package/dist/internal/verifySignedAuthResponse.d.ts +0 -6
  27. package/dist/internal/verifySignedAuthResponse.d.ts.map +0 -1
  28. package/dist/internal/verifySignedAuthResponse.js +0 -23
  29. package/dist/middleware/ensureCookies.d.ts +0 -8
  30. package/dist/middleware/ensureCookies.d.ts.map +0 -1
  31. package/dist/middleware/ensureCookies.js +0 -78
  32. package/dist/middleware/requireAuth.d.ts +0 -53
  33. package/dist/middleware/requireAuth.d.ts.map +0 -1
  34. package/dist/middleware/requireAuth.js +0 -118
  35. package/dist/middleware/requireRole.d.ts +0 -49
  36. package/dist/middleware/requireRole.d.ts.map +0 -1
  37. package/dist/middleware/requireRole.js +0 -77
  38. package/dist/types.d.ts +0 -9
  39. package/dist/types.d.ts.map +0 -1
  40. package/dist/types.js +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"requireAuth.d.ts","sourceRoot":"","sources":["../../src/middleware/requireAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAM1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,WAAW,CACzB,UAAU,SAAoB,EAC9B,iBAAiB,SAAqB,EACtC,YAAY,SAAM,IAahB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,MAAM,YAAY,KACjB,OAAO,CAAC,IAAI,CAAC,CA+EjB"}
@@ -1,118 +0,0 @@
1
- import jwt from "jsonwebtoken";
2
- import { refreshAccessToken } from "../internal/refreshAccessToken.js";
3
- import { setSessionCookie } from "../internal/cookie.js";
4
- /**
5
- * Express middleware that enforces authentication using Seamless Auth cookies.
6
- *
7
- * This guard verifies the signed access cookie generated by the Seamless Auth
8
- * server. If the access cookie is valid and unexpired, the decoded session
9
- * payload is attached to `req.user` and the request proceeds.
10
- *
11
- * If the access cookie is expired or missing *but* a valid refresh cookie is
12
- * present, the middleware automatically attempts a silent token refresh using
13
- * the Seamless Auth server. When successful, new session cookies are issued and
14
- * the request continues with an updated `req.user`.
15
- *
16
- * If neither the access token nor refresh token can validate the session,
17
- * the middleware returns a 401 Unauthorized error and prevents further
18
- * route execution.
19
- *
20
- * ### Responsibilities
21
- * - Validates the Seamless Auth session access cookie
22
- * - Attempts refresh-token–based session renewal when necessary
23
- * - Populates `req.user` with the verified session payload
24
- * - Handles all cookie rewriting during refresh flows
25
- * - Acts as a request-level authentication guard for API routes
26
- *
27
- * ### Cookie Parameters
28
- * - **cookieName** — Name of the access cookie that holds the signed session JWT
29
- * - **refreshCookieName** — Name of the refresh cookie used for silent token refresh
30
- * - **cookieDomain** — Domain or path value applied to issued cookies
31
- *
32
- * ### Example
33
- * ```ts
34
- * // Protect a route
35
- * app.get("/api/me", requireAuth(), (req, res) => {
36
- * res.json({ user: req.user });
37
- * });
38
- *
39
- * // Custom cookie names (if your Seamless Auth server uses overrides)
40
- * app.use(
41
- * "/internal",
42
- * requireAuth("sa_access", "sa_refresh", "mycompany.com"),
43
- * internalRouter
44
- * );
45
- * ```
46
- *
47
- * @param cookieName - The access cookie name. Defaults to `"seamless-access"`.
48
- * @param refreshCookieName - The refresh cookie name used for session rotation. Defaults to `"seamless-refresh"`.
49
- * @param cookieDomain - Domain or path used when rewriting cookies. Defaults to `"/"`.
50
- *
51
- * @returns An Express middleware function that enforces Seamless Auth
52
- * authentication on incoming requests.
53
- */
54
- export function requireAuth(cookieName = "seamless-access", refreshCookieName = "seamless-refresh", cookieDomain = "/") {
55
- const COOKIE_SECRET = process.env.SEAMLESS_COOKIE_SIGNING_KEY;
56
- if (!COOKIE_SECRET) {
57
- console.warn("[SeamlessAuth] SEAMLESS_COOKIE_SIGNING_KEY missing — requireAuth will always fail.");
58
- throw new Error("Missing required env SEAMLESS_COOKIE_SIGNING_KEY");
59
- }
60
- const AUTH_SERVER_URL = process.env.AUTH_SERVER_URL;
61
- return async (req, res, next) => {
62
- try {
63
- if (!COOKIE_SECRET) {
64
- throw new Error("Missing required SEAMLESS_COOKIE_SIGNING_KEY env");
65
- }
66
- const token = req.cookies?.[cookieName];
67
- if (!token) {
68
- res.status(401).json({ error: "Missing access cookie" });
69
- return;
70
- }
71
- try {
72
- const payload = jwt.verify(token, COOKIE_SECRET, {
73
- algorithms: ["HS256"],
74
- });
75
- req.user = payload;
76
- return next();
77
- }
78
- catch (err) {
79
- // expired or invalid token
80
- if (err.name !== "TokenExpiredError") {
81
- console.warn("[SeamlessAuth] Invalid token:", err.message);
82
- res.status(401).json({ error: "Invalid token" });
83
- return;
84
- }
85
- // Try refresh
86
- const refreshToken = req.cookies?.[refreshCookieName];
87
- if (!refreshToken) {
88
- res.status(401).json({ error: "Session expired; re-login required" });
89
- return;
90
- }
91
- console.log("[SeamlessAuth] Access token expired — attempting refresh");
92
- const refreshed = await refreshAccessToken(req, AUTH_SERVER_URL, refreshToken);
93
- if (!refreshed?.token) {
94
- res.status(401).json({ error: "Refresh failed" });
95
- return;
96
- }
97
- // Update cookie with new access token
98
- setSessionCookie(res, {
99
- sub: refreshed.sub,
100
- token: refreshed.token,
101
- roles: refreshed.roles,
102
- }, cookieDomain, refreshed.ttl, cookieName);
103
- setSessionCookie(res, { sub: refreshed.sub, refreshToken: refreshed.refreshToken }, req.hostname, refreshed.refreshTtl, refreshCookieName);
104
- // Decode new token so downstream has user
105
- const payload = jwt.verify(refreshed.token, COOKIE_SECRET, {
106
- algorithms: ["HS256"],
107
- });
108
- req.user = payload;
109
- next();
110
- }
111
- }
112
- catch (err) {
113
- console.error("[SeamlessAuth] requireAuth error:", err.message);
114
- res.status(401).json({ error: "Invalid or expired access cookie" });
115
- return;
116
- }
117
- };
118
- }
@@ -1,49 +0,0 @@
1
- import { RequestHandler } from "express";
2
- /**
3
- * Express middleware that enforces role-based authorization for Seamless Auth sessions.
4
- *
5
- * This guard assumes that `requireAuth()` has already validated the request
6
- * and populated `req.user` with the decoded Seamless Auth session payload.
7
- * It then checks whether the user’s roles include the required role (or any
8
- * of several, when an array is provided).
9
- *
10
- * If the user possesses the required authorization, the request proceeds.
11
- * Otherwise, the middleware responds with a 403 Forbidden error.
12
- *
13
- * ### Responsibilities
14
- * - Validates that `req.user` is present (enforced upstream by `requireAuth`)
15
- * - Ensures the authenticated user includes the specified role(s)
16
- * - Blocks unauthorized access with a standardized JSON 403 response
17
- *
18
- * ### Parameters
19
- * - **requiredRole** — A role (string) or list of roles the user must have.
20
- * If an array is provided, *any* matching role grants access.
21
- * - **cookieName** — Optional name of the access cookie to inspect.
22
- * Defaults to `"seamless-access"`, but typically not needed because
23
- * `requireAuth` is expected to run first.
24
- *
25
- * ### Example
26
- * ```ts
27
- * // Require a single role
28
- * app.get("/admin/users",
29
- * requireAuth(),
30
- * requireRole("admin"),
31
- * (req, res) => {
32
- * res.send("Welcome admin!");
33
- * }
34
- * );
35
- *
36
- * // Allow any of multiple roles
37
- * app.post("/settings",
38
- * requireAuth(),
39
- * requireRole(["admin", "supervisor"]),
40
- * updateSettingsHandler
41
- * );
42
- * ```
43
- *
44
- * @param requiredRole - A role or list of roles required to access the route.
45
- * @param cookieName - Optional access cookie name (defaults to `seamless-access`).
46
- * @returns An Express middleware function enforcing role-based access control.
47
- */
48
- export declare function requireRole(role: string, cookieName?: string): RequestHandler;
49
- //# sourceMappingURL=requireRole.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"requireRole.d.ts","sourceRoot":"","sources":["../../src/middleware/requireRole.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAC;AAG1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,SAAoB,GAC7B,cAAc,CAiChB"}
@@ -1,77 +0,0 @@
1
- import jwt from "jsonwebtoken";
2
- /**
3
- * Express middleware that enforces role-based authorization for Seamless Auth sessions.
4
- *
5
- * This guard assumes that `requireAuth()` has already validated the request
6
- * and populated `req.user` with the decoded Seamless Auth session payload.
7
- * It then checks whether the user’s roles include the required role (or any
8
- * of several, when an array is provided).
9
- *
10
- * If the user possesses the required authorization, the request proceeds.
11
- * Otherwise, the middleware responds with a 403 Forbidden error.
12
- *
13
- * ### Responsibilities
14
- * - Validates that `req.user` is present (enforced upstream by `requireAuth`)
15
- * - Ensures the authenticated user includes the specified role(s)
16
- * - Blocks unauthorized access with a standardized JSON 403 response
17
- *
18
- * ### Parameters
19
- * - **requiredRole** — A role (string) or list of roles the user must have.
20
- * If an array is provided, *any* matching role grants access.
21
- * - **cookieName** — Optional name of the access cookie to inspect.
22
- * Defaults to `"seamless-access"`, but typically not needed because
23
- * `requireAuth` is expected to run first.
24
- *
25
- * ### Example
26
- * ```ts
27
- * // Require a single role
28
- * app.get("/admin/users",
29
- * requireAuth(),
30
- * requireRole("admin"),
31
- * (req, res) => {
32
- * res.send("Welcome admin!");
33
- * }
34
- * );
35
- *
36
- * // Allow any of multiple roles
37
- * app.post("/settings",
38
- * requireAuth(),
39
- * requireRole(["admin", "supervisor"]),
40
- * updateSettingsHandler
41
- * );
42
- * ```
43
- *
44
- * @param requiredRole - A role or list of roles required to access the route.
45
- * @param cookieName - Optional access cookie name (defaults to `seamless-access`).
46
- * @returns An Express middleware function enforcing role-based access control.
47
- */
48
- export function requireRole(role, cookieName = "seamless-access") {
49
- return (req, res, next) => {
50
- try {
51
- const COOKIE_SECRET = process.env.SEAMLESS_COOKIE_SIGNING_KEY;
52
- if (!COOKIE_SECRET) {
53
- console.warn("[SeamlessAuth] SEAMLESS_COOKIE_SIGNING_KEY missing — requireRole will always fail.");
54
- throw new Error("Missing required env SEAMLESS_COOKIE_SIGNING_KEY");
55
- }
56
- const token = req.cookies?.[cookieName];
57
- if (!token) {
58
- res.status(401).json({ error: "Missing access cookie" });
59
- return;
60
- }
61
- // Verify JWT signature
62
- const payload = jwt.verify(token, COOKIE_SECRET, {
63
- algorithms: ["HS256"],
64
- });
65
- // Check role membership
66
- if (!payload.roles?.includes(role)) {
67
- res.status(403).json({ error: `Forbidden: ${role} role required` });
68
- return;
69
- }
70
- next();
71
- }
72
- catch (err) {
73
- console.error(`[RequireRole] requireRole(${role}) failed:`, err.message);
74
- res.status(401).json({ error: "Invalid or expired access cookie" });
75
- }
76
- };
77
- }
package/dist/types.d.ts DELETED
@@ -1,9 +0,0 @@
1
- export interface SeamlessAuthServerOptions {
2
- authServerUrl: string;
3
- cookieDomain?: string;
4
- accesscookieName?: string;
5
- registrationCookieName?: string;
6
- refreshCookieName?: string;
7
- preAuthCookieName?: string;
8
- }
9
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B"}
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};