@seamless-auth/express 0.0.2-beta.2 → 0.0.2-beta.21

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 ADDED
@@ -0,0 +1,79 @@
1
+ GNU AFFERO GENERAL PUBLIC LICENSE
2
+ Version 3, 19 November 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc.
5
+ <https://fsf.org/>
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ This license is identical to the GNU General Public License, except that it also
10
+ ensures that software running as a network service makes its source code
11
+ available to users.
12
+
13
+ ---
14
+
15
+ TERMS AND CONDITIONS
16
+
17
+ 0. Definitions.
18
+
19
+ “This License” refers to version 3 of the GNU Affero General Public License.
20
+
21
+ “Copyright” also means copyright-like laws that apply to other kinds of works,
22
+ such as semiconductor masks.
23
+
24
+ The “Program” refers to any copyrightable work licensed under this License.
25
+ Each licensee is addressed as “you”.
26
+
27
+ To “modify” a work means to copy from or adapt all or part of the work in a
28
+ fashion requiring copyright permission, other than the making of an exact copy.
29
+
30
+ To “propagate” a work means to do anything with it that, without permission,
31
+ would make you directly or secondarily liable for infringement under applicable
32
+ copyright law, except executing it on a computer or modifying a private copy.
33
+
34
+ To “convey” a work means any kind of propagation that enables other parties to
35
+ make or receive copies.
36
+
37
+ An interactive user interface displays “Appropriate Legal Notices” to the extent
38
+ that it includes a convenient and prominently visible feature that displays an
39
+ appropriate copyright notice, and tells the user that there is no warranty for
40
+ the work (except to the extent that warranties are provided), that licensees may
41
+ convey the work under this License, and how to view a copy of this License.
42
+
43
+ ---
44
+
45
+ 13. Remote Network Interaction; Use with the GNU General Public License.
46
+
47
+ Notwithstanding any other provision of this License, if you modify the Program,
48
+ your modified version must prominently offer all users interacting with it
49
+ remotely through a computer network an opportunity to receive the Corresponding
50
+ Source of your version by providing access to the Corresponding Source from a
51
+ network server at no charge, through some standard or customary means of
52
+ facilitating copying of software.
53
+
54
+ ---
55
+
56
+ 15. Disclaimer of Warranty.
57
+
58
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
59
+ EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
60
+ PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
61
+ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
63
+
64
+ ---
65
+
66
+ 16. Limitation of Liability.
67
+
68
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
69
+ COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
70
+ PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
71
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
72
+ THE PROGRAM.
73
+
74
+ ---
75
+
76
+ END OF TERMS AND CONDITIONS
77
+
78
+ You should have received a copy of the GNU Affero General Public License along
79
+ with this program. If not, see <https://www.gnu.org/licenses/>.
package/LICENSE.md ADDED
@@ -0,0 +1,26 @@
1
+ # License
2
+
3
+ Seamless Auth Server - Express ("@seamlessauth/express") is licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0-only)**.
4
+
5
+ - SPDX: `AGPL-3.0-only`
6
+
7
+ ## What this means (high level)
8
+
9
+ - You are free to **use**, **modify**, and **self-host** this software.
10
+ - If you **modify** this software and **run it as a network service** (for example, hosting it for others to use), you must **make the complete corresponding source code of your modified version available** to users of that service, under the AGPL.
11
+
12
+ This summary is not legal advice and does not replace the license text.
13
+
14
+ ## Full license text
15
+
16
+ The full license text is available here:
17
+
18
+ - https://www.gnu.org/licenses/agpl-3.0.html
19
+
20
+ You should include a copy of the AGPLv3 license in your distribution. If this repository does not contain the full license text yet, add it as `LICENSE` or `LICENSE.txt` (recommended), and keep this `LICENSE.md` as the human-friendly summary.
21
+
22
+ ## Commercial licensing
23
+
24
+ If you would like to embed Seamless Auth API into a proprietary product, redistribute it under different terms, or offer it as a managed service without AGPL obligations, commercial licensing may be available.
25
+
26
+ Contact: support@seamlessauth.com
package/README.md CHANGED
@@ -1,78 +1,92 @@
1
- # @seamless-auth/server-express
1
+ # @seamless-auth/express
2
2
 
3
- ### Seamless Auth Express Adapter
3
+ [![npm version](https://img.shields.io/npm/v/@seamless-auth/express.svg)](https://www.npmjs.com/package/@seamless-auth/express)
4
+ [![test coverage](https://img.shields.io/badge/coverage-coming%20soon-lightgrey)](#testing)
5
+ [![license](https://img.shields.io/badge/license-AGPL--3.0-blue)](#license)
4
6
 
5
- A secure, passwordless **server-side adapter** that connects your Express API to a private Seamless Auth Server.
7
+ ### Seamless Auth Express Adapter
6
8
 
7
- It proxies all authentication flows, manages signed cookies, and gives you out-of-the-box middleware for verifying users and enforcing roles.
9
+ A secure, passwordless **server-side adapter** for Express that connects your API to a private **Seamless Auth Server**.
10
+
11
+ This package:
12
+
13
+ - Proxies authentication flows
14
+ - Manages signed, HttpOnly session cookies
15
+ - Enforces authentication and authorization in your API
16
+ - Handles all API ↔ Auth Server communication via short-lived service tokens
8
17
 
9
18
  > **npm:** https://www.npmjs.com/package/@seamless-auth/express
10
19
  > **Docs:** https://docs.seamlessauth.com
11
20
  > **Repo:** https://github.com/fells-code/seamless-auth-server
12
21
 
13
- > Couple with https://github.com/fells-code/seamless-auth/react for an end to end seamless experience
14
-
15
- > Or get a full starter application with https://github.com/fells-code/create-seamless
22
+ Pair this with:
16
23
 
17
- ---
24
+ - **React SDK:** https://github.com/fells-code/seamless-auth-react
25
+ - **Starter app:** https://github.com/fells-code/create-seamless
18
26
 
19
27
  ---
20
28
 
21
29
  ## Installation
22
30
 
23
31
  ```bash
24
- npm install @seamless-auth/server-express
32
+ npm install @seamless-auth/express
25
33
  # or
26
- yarn add @seamless-auth/server-express
34
+ yarn add @seamless-auth/express
27
35
  ```
28
36
 
29
- ## Quick Example
37
+ ---
38
+
39
+ ## Quick Start
30
40
 
31
41
  ```ts
32
42
  import express from "express";
33
43
  import cookieParser from "cookie-parser";
34
- import createSeamlessAuthServer, {
44
+ import {
45
+ createSeamlessAuthServer,
35
46
  requireAuth,
36
47
  requireRole,
37
- } from "@seamless-auth/server-express";
48
+ } from "@seamless-auth/express";
38
49
 
39
50
  const app = express();
51
+ app.use(express.json());
40
52
  app.use(cookieParser());
41
53
 
42
- // Public Seamless Auth endpoints
54
+ // Mount Seamless Auth routes
43
55
  app.use(
44
56
  "/auth",
45
- createSeamlessAuthServer({ authServerUrl: process.env.AUTH_SERVER_URL! })
57
+ createSeamlessAuthServer({
58
+ authServerUrl: process.env.AUTH_SERVER_URL!,
59
+ }),
46
60
  );
47
61
 
48
- // Everything after this line requires authentication
62
+ // Everything below requires authentication
49
63
  app.use(requireAuth());
50
64
 
51
- app.get("/api/me", (req, res) => res.json({ user: (req as any).user }));
52
- app.get("/admin", requireRole("admin"), (req, res) =>
53
- res.json({ message: "Welcome admin!" })
54
- );
65
+ app.get("/api/me", (req, res) => {
66
+ res.json({ user: req.user });
67
+ });
68
+
69
+ app.get("/admin", requireRole("admin"), (req, res) => {
70
+ res.json({ message: "Welcome admin!" });
71
+ });
55
72
 
56
- app.listen(5000, () => console.log("Portal API running on :5000"));
73
+ app.listen(5000, () => console.log("API running on http://localhost:3000"));
57
74
  ```
58
75
 
59
76
  ---
60
77
 
61
- # Full Documentation
62
-
63
78
  ## Overview
64
79
 
65
- `@seamless-auth/express` lets your backend API act as an authentication and authorization server using Seamless Auth.
80
+ `@seamless-auth/express` lets your backend API act as the **security boundary** for authentication and authorization.
66
81
 
67
- It transparently proxies and validates authentication flows so your frontend can use a single API endpoint for:
82
+ Your API:
68
83
 
69
- - Login / Registration / Logout
70
- - User introspection (`/auth/me`)
71
- - Session cookies (signed JWTs)
72
- - Role & permission guards
73
- - Internal Auth Server communication (JWKS + service tokens)
84
+ - owns user session cookies
85
+ - verifies identity locally
86
+ - asserts identity upstream using service tokens
87
+ - never forwards browser cookies to the Auth Server
74
88
 
75
- Everything happens securely between your API and a private Seamless Auth Server.
89
+ This keeps trust boundaries clean and auditable.
76
90
 
77
91
  ---
78
92
 
@@ -84,9 +98,9 @@ Everything happens securely between your API and a private Seamless Auth Server.
84
98
 
85
99
  [Your Express API]
86
100
  ├─ createSeamlessAuthServer() ← mounts /auth routes
87
- ├─ requireAuth() ← verifies signed cookie JWT
88
- ├─ requireRole('admin') ← role-based guard
89
- └─ getSeamlessUser() ← calls Auth Server
101
+ ├─ requireAuth() ← verifies access cookie
102
+ ├─ requireRole("admin") ← role-based guard
103
+ └─ getSeamlessUser() ← optional user hydration
90
104
 
91
105
 
92
106
  [Private Seamless Auth Server]
@@ -96,12 +110,17 @@ Everything happens securely between your API and a private Seamless Auth Server.
96
110
 
97
111
  ## Environment Variables
98
112
 
99
- | Variable | Description | Example |
100
- | ----------------------------- | --------------------------------------------- | ------------------------------ |
101
- | `AUTH_SERVER_URL` | Base URL of your Seamless Auth Server | `https://auth.client.com` |
102
- | `SEAMLESS_COOKIE_SIGNING_KEY` | Secret key for signing JWT cookies | `base64:...` |
103
- | `SEAMLESS_SERVICE_TOKEN` | Private key for API → Auth Server JWTs | `Obtained via the auth portal` |
104
- | `FRONTEND_URL` | URL of your website or https://localhost:5001 | `https://mySite.com` |
113
+ | Variable | Description | Example |
114
+ | -------------------- | ----------------------------------------- | ------------------------- |
115
+ | `AUTH_SERVER_URL` | Base URL of your Seamless Auth Server | `https://auth.client.com` |
116
+ | `COOKIE_SIGNING_KEY` | Secret for signing API session cookies | `local-dev-secret` |
117
+ | `API_SERVICE_TOKEN` | API → Auth Server service secret | `shared-m2m-value` |
118
+ | `APP_ORIGIN` | Your site URL (or localhost in demo mode) | `https://myapp.com` |
119
+ | `DB_HOST` | Database Host | `localhost` |
120
+ | `DB_PORT` | Database Port | `5432` |
121
+ | `DB_USER` | Database user | `myuser` |
122
+ | `DB_PASSWORD` | Database password | `mypassword` |
123
+ | `DB_NAME` | Name of your database | `seamless` |
105
124
 
106
125
  ---
107
126
 
@@ -109,35 +128,35 @@ Everything happens securely between your API and a private Seamless Auth Server.
109
128
 
110
129
  ### `createSeamlessAuthServer(options)`
111
130
 
112
- Mounts an Express router exposing the full Seamless Auth flow:
131
+ Mounts an Express router that exposes the full Seamless Auth flow under `/auth`.
132
+
133
+ Routes include:
113
134
 
114
135
  - `/auth/login/start`
115
136
  - `/auth/login/finish`
116
- - `/auth/webauthn/...`
117
- - `/auth/registration/...`
118
- - `/auth/me`
137
+ - `/auth/webauthn/*`
138
+ - `/auth/registration/*`
139
+ - `/auth/users/me`
119
140
  - `/auth/logout`
120
141
 
121
142
  **Options**
122
143
 
123
144
  ```ts
124
145
  {
125
- authServerUrl: string; // required
126
- cookieDomain?: string;
127
- cookieNameOverrides?: {
128
- preauth?: string;
129
- registration?: string;
130
- access?: string;
131
- };
146
+ authServerUrl: string; // required
147
+ cookieDomain?: string; // optional (defaults to host)
148
+ accessCookieName?: string;
149
+ registrationCookieName?: string;
150
+ refreshCookieName?: string;
151
+ preAuthCookieName?: string;
132
152
  }
133
153
  ```
134
154
 
135
155
  ---
136
156
 
137
- ### `requireAuth(cookieName?: string)`
157
+ ### `requireAuth(options?)`
138
158
 
139
- Middleware that validates the signed access cookie (`seamless_auth_access` by default)
140
- and attaches the decoded user payload to `req.user`.
159
+ Express middleware that verifies a signed access cookie and attaches the decoded user payload to `req.user`.
141
160
 
142
161
  ```ts
143
162
  app.get("/api/profile", requireAuth(), (req, res) => {
@@ -147,10 +166,11 @@ app.get("/api/profile", requireAuth(), (req, res) => {
147
166
 
148
167
  ---
149
168
 
150
- ### `requireRole(role: string, cookieName?: string)`
169
+ ### `requireRole(role: string)`
170
+
171
+ Role-based authorization middleware.
151
172
 
152
- Role-based authorization guard.
153
- Blocks non-matching roles with HTTP 403.
173
+ Blocks requests when the authenticated user does not have the required role.
154
174
 
155
175
  ```ts
156
176
  app.get("/admin", requireRole("admin"), (req, res) => {
@@ -162,108 +182,67 @@ app.get("/admin", requireRole("admin"), (req, res) => {
162
182
 
163
183
  ### `getSeamlessUser(req, authServerUrl, cookieName?)`
164
184
 
165
- Calls the Auth Server’s `/internal/session/introspect` endpoint using a signed service JWT
166
- and returns the Seamless user object.
185
+ Optional helper that calls the Auth Server to retrieve the **fully hydrated user object**.
186
+
187
+ This does **not** enforce authentication.
167
188
 
168
189
  ```ts
169
- const user = await getSeamlessUser(req, process.env.AUTH_SERVER_URL!);
190
+ const user = await getSeamlessUser(req, process.env.AUTH_SERVER_URL);
170
191
  ```
171
192
 
172
- User shape
193
+ Returned shape (example):
173
194
 
174
195
  ```ts
175
196
  {
176
197
  id: string;
177
198
  email: string;
178
199
  phone: string;
179
- roles: string[]
200
+ roles: string[];
180
201
  }
181
202
  ```
182
203
 
204
+ ---
205
+
183
206
  ## End-to-End Flow
184
207
 
185
208
  1. **Frontend** → `/auth/login/start`
186
- API proxies to Seamless Auth Server
187
- → sets short-lived pre-auth cookie.
209
+ API proxies request and sets a short-lived _pre-auth_ cookie.
188
210
 
189
211
  2. **Frontend** → `/auth/webauthn/finish`
190
- API proxies, validates, sets access cookie (`seamless-access`).
212
+ API verifies response and sets a signed access cookie.
191
213
 
192
- 3. **Subsequent API calls** → `/api/...`
193
- `requireAuth()` verifies cookie and attaches user.
194
- → Role routes use `requireRole()`.
214
+ 3. **API routes** → `/api/*`
215
+ `requireAuth()` verifies the cookie and attaches `req.user`.
195
216
 
196
217
  ---
197
218
 
198
219
  ## Local Development
199
220
 
200
- In order to develop with your Seamless Auth server instance, you will need to have:
201
-
202
- - Created an account @ https://dashboard.seamlessauth.com
203
- - Created a new Seamless Auth application
204
-
205
- Example env:
206
-
207
221
  ```bash
208
- AUTH_SERVER_URL=https://<identifier>.seamlessauth.com # Found in the portal
209
- SEAMLESS_SERVICE_TOKEN=32byte-secret # Created and rotated in the portal
210
- FRONTEND_URL=https://yourSite.com # Must match the value you have for Frontend Domain in the portal (Can be localhost:5001 when application is in demo mode)
211
- SEAMLESS_COOKIE_SIGNING_KEY=local-secret-key # A key you make for signing your API's distributed cookies
222
+ AUTH_SERVER_URL=http://localhost:5312
223
+ SEAMLESS_SERVICE_TOKEN=generated-secret
224
+ COOKIE_SIGNING_KEY=local-dev-key
225
+ FRONTEND_URL=http://localhost:5001
212
226
  ```
213
227
 
214
228
  ---
215
229
 
216
- ## Example Middleware Stack
217
-
218
- ```ts
219
- const AUTH_SERVER_URL = process.env.AUTH_SERVER_URL!;
220
- app.use(cors({ origin: "https://localhost:5001", credentials: true }));
221
- app.use(express.json());
222
- app.use(cookieParser());
223
- app.use("/auth", createSeamlessAuthServer({ authServerUrl: AUTH_SERVER_URL }));
224
- app.use(requireAuth());
225
- ```
226
-
227
- ---
228
-
229
- ## Security Model
230
-
231
- | Layer | Auth Mechanism | Signed By |
232
- | --------------------- | ------------------------------------- | ------------------ |
233
- | **Frontend ↔ API** | Signed JWT in HttpOnly cookie (HS256) | Client API |
234
- | **API ↔ Auth Server** | Bearer Service JWT (RS256) | API’s private key |
235
- | **Auth Server** | Validates service tokens via JWKS | Seamless Auth JWKS |
236
-
237
- All tokens and cookies are stateless and cryptographically verifiable.
238
-
239
- ---
240
-
241
230
  ## Testing
242
231
 
243
- You can mock `requireAuth` and test Express routes via `supertest`.
244
-
245
- Example:
232
+ This package includes **Express smoke tests** using `supertest`.
246
233
 
247
- ```ts
248
- import { requireAuth } from "@seamless-auth/server-express";
249
- app.get("/api/test", requireAuth(), (req, res) => res.json({ ok: true }));
250
- ```
234
+ Core authentication logic is tested separately in `@seamless-auth/core`.
251
235
 
252
236
  ---
253
237
 
254
- ## Roadmap
238
+ ## License
255
239
 
256
- | Feature | Status |
257
- | -------------------------------------------- | ----------- |
258
- | JWKS-verified response signing | ✅ |
259
- | OIDC discovery & SSO readiness | planned |
260
- | Federation (Google / Okta) | future |
261
- | Multi-framework adapters (Next.js / Fastify) | coming soon |
240
+ **AGPL-3.0-only** © 2026 Fells Code LLC
262
241
 
263
- ---
242
+ This license ensures:
264
243
 
265
- ## License
244
+ - transparency of security-critical code
245
+ - freedom to self-host and modify
246
+ - sustainability of the managed service offering
266
247
 
267
- MIT © 2025 Fells Code LLC
268
- Part of the **Seamless Auth** ecosystem.
269
- https://seamlessauth.com
248
+ See [`LICENSE`](./LICENSE) for details.
@@ -0,0 +1,197 @@
1
+ import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
2
+
3
+ type SeamlessAuthServerOptions = {
4
+ authServerUrl: string;
5
+ cookieSecret: string;
6
+ serviceSecret: string;
7
+ issuer: string;
8
+ audience: string;
9
+ jwksKid?: string;
10
+ cookieDomain?: string;
11
+ accessCookieName?: string;
12
+ registrationCookieName?: string;
13
+ refreshCookieName?: string;
14
+ preAuthCookieName?: string;
15
+ };
16
+ interface SeamlessAuthUser {
17
+ id: string;
18
+ sub: string;
19
+ roles: string[];
20
+ email: string;
21
+ phone: string;
22
+ iat?: number;
23
+ exp?: number;
24
+ }
25
+ /**
26
+ * Creates an Express Router that proxies all authentication traffic to a Seamless Auth server.
27
+ *
28
+ * This helper wires your API backend to a Seamless Auth instance running in
29
+ * "server mode." It automatically forwards login, registration, WebAuthn,
30
+ * logout, token refresh, and session validation routes to the auth server
31
+ * and handles all cookie management required for a seamless login flow.
32
+ *
33
+ * ### Responsibilities
34
+ * - Proxies all `/auth/*` routes to the upstream Seamless Auth server
35
+ * - Manages `access`, `registration`, `pre-auth`, and `refresh` cookies
36
+ * - Normalizes cookie settings for cross-domain or same-domain deployments
37
+ * - Ensures authentication routes behave consistently across environments
38
+ * - Provides shared middleware for auth flows
39
+ *
40
+ * ### Cookie Types
41
+ * - **accessCookie** – long-lived session cookie for authenticated API requests
42
+ * - **registrationCookie** – ephemeral cookie used during registration and OTP/WebAuthn flows
43
+ * - **preAuthCookie** – short-lived cookie used during login initiation
44
+ * - **refreshCookie** – opaque refresh token cookie used to rotate session tokens
45
+ *
46
+ * All cookie names and their domains may be customized via the `opts` parameter.
47
+ *
48
+ * ### Example
49
+ * ```ts
50
+ * app.use("/auth", createSeamlessAuthServer({
51
+ * authServerUrl: "https://identifier.seamlessauth.com",
52
+ * cookieDomain: "mycompany.com",
53
+ * cookieSecret: "someLongRandomValue"
54
+ * serviceSecret: "someLongRandomValueToo"
55
+ * jwksKid: "dev-main"
56
+ * accessCookieName: "sa_access",
57
+ * registrationCookieName: "sa_registration",
58
+ * refreshCookieName: "sa_refresh",
59
+ * }));
60
+ * ```
61
+ *
62
+ * @param opts - Configuration options for the Seamless Auth proxy:
63
+ * - `authServerUrl` — Base URL of your Seamless Auth instance (required)
64
+ * - `cookieSecret` — The value to encode your cookies secrets with (required)
65
+ * - `serviceSecret` - An machine to machine shared secret that matches your auth servers (required)
66
+ * - `jwksKid` - The active jwks KID
67
+ * - `cookieDomain` — Domain attribute applied to all auth cookies
68
+ * - `accessCookieName` — Name of the session access cookie
69
+ * - `registrationCookieName` — Name of the ephemeral registration cookie
70
+ * - `refreshCookieName` — Name of the refresh token cookie
71
+ * - `preAuthCookieName` — Name of the cookie used during login initiation
72
+ *
73
+ * @returns An Express `Router` preconfigured with all Seamless Auth routes.
74
+ */
75
+ declare function createSeamlessAuthServer(opts: SeamlessAuthServerOptions): Router;
76
+
77
+ interface RequireAuthOptions {
78
+ cookieName?: string;
79
+ cookieSecret: string;
80
+ }
81
+ /**
82
+ * Express middleware that enforces authentication using Seamless Auth cookies.
83
+ *
84
+ * This guard verifies the signed access cookie generated by the Seamless Auth
85
+ * server. If the access cookie is valid and unexpired, the decoded session
86
+ * payload is attached to `req.user` and the request proceeds.
87
+ *
88
+ * If the access cookie is expired or missing *but* a valid refresh cookie is
89
+ * present, the middleware automatically attempts a silent token refresh using
90
+ * the Seamless Auth server. When successful, new session cookies are issued and
91
+ * the request continues with an updated `req.user`.
92
+ *
93
+ * If neither the access token nor refresh token can validate the session,
94
+ * the middleware returns a 401 Unauthorized error and prevents further
95
+ * route execution.
96
+ *
97
+ * ### Responsibilities
98
+ * - Validates the Seamless Auth session access cookie
99
+ * - Attempts refresh-token–based session renewal when necessary
100
+ * - Populates `req.user` with the verified session payload
101
+ * - Handles all cookie rewriting during refresh flows
102
+ * - Acts as a request-level authentication guard for API routes
103
+ *
104
+ * ### Cookie Parameters
105
+ * - **cookieName** — Name of the access cookie that holds the signed session JWT
106
+ * - **refreshCookieName** — Name of the refresh cookie used for silent token refresh
107
+ * - **cookieDomain** — Domain or path value applied to issued cookies
108
+ *
109
+ * ### Example
110
+ * ```ts
111
+ * // Protect a route
112
+ * app.get("/api/me", requireAuth(), (req, res) => {
113
+ * res.json({ user: req.user });
114
+ * });
115
+ *
116
+ * // Custom cookie names (if your Seamless Auth server uses overrides)
117
+ * app.use(
118
+ * "/internal",
119
+ * requireAuth("sa_access", "sa_refresh", "mycompany.com"),
120
+ * internalRouter
121
+ * );
122
+ * ```
123
+ *
124
+ * @param cookieName - The access cookie name. Defaults to `"seamless-access"`.
125
+ * @param refreshCookieName - The refresh cookie name used for session rotation. Defaults to `"seamless-refresh"`.
126
+ * @param cookieDomain - Domain or path used when rewriting cookies. Defaults to `"/"`.
127
+ *
128
+ * @returns An Express middleware function that enforces Seamless Auth
129
+ * authentication on incoming requests.
130
+ */
131
+ interface RequireAuthOptions {
132
+ cookieName?: string;
133
+ cookieSecret: string;
134
+ }
135
+ /**
136
+ * Express middleware that enforces authentication
137
+ * using an already-issued Seamless Auth access cookie.
138
+ *
139
+ * NOTE:
140
+ * - This middleware does NOT attempt token refresh.
141
+ * - Refresh is handled upstream by ensureCookies().
142
+ */
143
+ declare function requireAuth(opts: RequireAuthOptions): (req: Request, res: Response, next: NextFunction) => void;
144
+
145
+ /**
146
+ * Express middleware that enforces role-based authorization for Seamless Auth.
147
+ *
148
+ * This middleware assumes `requireAuth()` has already:
149
+ * - authenticated the request
150
+ * - populated `req.user` with the authenticated session payload
151
+ *
152
+ * `requireRole` performs **authorization only**. It does not inspect cookies,
153
+ * verify tokens, or read environment variables.
154
+ *
155
+ * If any of the required roles are present on the user, access is granted.
156
+ * Otherwise, a 403 Forbidden response is returned.
157
+ *
158
+ * * ### Example
159
+ * ```ts
160
+ * // Require a single role
161
+ * app.get("/admin/users",
162
+ * requireAuth(),
163
+ * requireRole("admin"),
164
+ * (req, res) => {
165
+ * res.send("Welcome admin!");
166
+ * }
167
+ * );
168
+ *
169
+ * // Allow any of multiple roles
170
+ * app.post("/settings",
171
+ * requireAuth(),
172
+ * requireRole(["admin", "supervisor"]),
173
+ * updateSettingsHandler
174
+ * );
175
+ *
176
+ * @param requiredRoles - A role or list of roles required to access the route
177
+ */
178
+ declare function requireRole(requiredRoles: string | string[]): RequestHandler;
179
+
180
+ interface EnsureCookiesMiddlewareOptions {
181
+ authServerUrl: string;
182
+ cookieDomain?: string;
183
+ accessCookieName: string;
184
+ registrationCookieName: string;
185
+ refreshCookieName: string;
186
+ preAuthCookieName: string;
187
+ cookieSecret: string;
188
+ serviceSecret: string;
189
+ issuer: string;
190
+ audience: string;
191
+ keyId: string;
192
+ }
193
+ declare function createEnsureCookiesMiddleware(opts: EnsureCookiesMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
194
+
195
+ declare function getSeamlessUser(req: Request, opts: SeamlessAuthServerOptions): Promise<any>;
196
+
197
+ export { type SeamlessAuthServerOptions, type SeamlessAuthUser, createEnsureCookiesMiddleware, createSeamlessAuthServer as default, getSeamlessUser, requireAuth, requireRole };