@seamless-auth/core 0.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/LICENSE +79 -0
- package/LICENSE.md +26 -0
- package/README.md +141 -0
- package/dist/authFetch.d.ts +8 -0
- package/dist/authFetch.d.ts.map +1 -0
- package/dist/authFetch.js +13 -0
- package/dist/authFetch.js.map +1 -0
- package/dist/createServiceToken.d.ts +10 -0
- package/dist/createServiceToken.d.ts.map +1 -0
- package/dist/createServiceToken.js +15 -0
- package/dist/createServiceToken.js.map +1 -0
- package/dist/ensureCookies.d.ts +42 -0
- package/dist/ensureCookies.d.ts.map +1 -0
- package/dist/ensureCookies.js +116 -0
- package/dist/ensureCookies.js.map +1 -0
- package/dist/getSeamlessUser.d.ts +7 -0
- package/dist/getSeamlessUser.d.ts.map +1 -0
- package/dist/getSeamlessUser.js +19 -0
- package/dist/getSeamlessUser.js.map +1 -0
- package/dist/handlers/finishLogin.d.ts +24 -0
- package/dist/handlers/finishLogin.d.ts.map +1 -0
- package/dist/handlers/finishLogin.js +48 -0
- package/dist/handlers/finishLogin.js.map +1 -0
- package/dist/handlers/finishRegister.d.ts +23 -0
- package/dist/handlers/finishRegister.d.ts.map +1 -0
- package/dist/handlers/finishRegister.js +47 -0
- package/dist/handlers/finishRegister.js.map +1 -0
- package/dist/handlers/login.d.ts +21 -0
- package/dist/handlers/login.d.ts.map +1 -0
- package/dist/handlers/login.js +34 -0
- package/dist/handlers/login.js.map +1 -0
- package/dist/handlers/logout.d.ts +12 -0
- package/dist/handlers/logout.d.ts.map +1 -0
- package/dist/handlers/logout.js +15 -0
- package/dist/handlers/logout.js.map +1 -0
- package/dist/handlers/me.d.ts +16 -0
- package/dist/handlers/me.d.ts.map +1 -0
- package/dist/handlers/me.js +25 -0
- package/dist/handlers/me.js.map +1 -0
- package/dist/handlers/register.d.ts +22 -0
- package/dist/handlers/register.d.ts.map +1 -0
- package/dist/handlers/register.js +27 -0
- package/dist/handlers/register.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/refreshAccessToken.d.ts +17 -0
- package/dist/refreshAccessToken.d.ts.map +1 -0
- package/dist/refreshAccessToken.js +26 -0
- package/dist/refreshAccessToken.js.map +1 -0
- package/dist/verifyCookieJwt.d.ts +3 -0
- package/dist/verifyCookieJwt.d.ts.map +1 -0
- package/dist/verifyCookieJwt.js +13 -0
- package/dist/verifyCookieJwt.js.map +1 -0
- package/dist/verifyRefreshCookie.d.ts +7 -0
- package/dist/verifyRefreshCookie.d.ts.map +1 -0
- package/dist/verifyRefreshCookie.js +12 -0
- package/dist/verifyRefreshCookie.js.map +1 -0
- package/dist/verifySignedAuthResponse.d.ts +2 -0
- package/dist/verifySignedAuthResponse.d.ts.map +1 -0
- package/dist/verifySignedAuthResponse.js +17 -0
- package/dist/verifySignedAuthResponse.js.map +1 -0
- package/package.json +56 -0
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 - Core ("@seamless-auth/core") 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
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @seamless-auth/core
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@seamless-auth/core)
|
|
4
|
+
[](#license "License")
|
|
5
|
+
|
|
6
|
+
### Seamless Auth – Core
|
|
7
|
+
|
|
8
|
+
`@seamless-auth/core` contains the **framework-agnostic authentication logic** that powers the Seamless Auth ecosystem.
|
|
9
|
+
|
|
10
|
+
It is designed to be:
|
|
11
|
+
|
|
12
|
+
- deterministic
|
|
13
|
+
- auditable
|
|
14
|
+
- testable
|
|
15
|
+
- independent of any web framework
|
|
16
|
+
|
|
17
|
+
If you are building a custom adapter (Express, Fastify, Next.js, Hono, etc.), this is the package you integrate with.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What This Package Is
|
|
22
|
+
|
|
23
|
+
- Core authentication state machine
|
|
24
|
+
- Cookie validation and refresh logic
|
|
25
|
+
- Service-token–based API ↔ Auth Server communication
|
|
26
|
+
- Stateless, cryptographically verifiable flows
|
|
27
|
+
|
|
28
|
+
This package **does not**:
|
|
29
|
+
|
|
30
|
+
- depend on Express or any framework
|
|
31
|
+
- read environment variables
|
|
32
|
+
- set cookies or headers directly
|
|
33
|
+
- manage HTTP requests or responses
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Who Should Use This
|
|
38
|
+
|
|
39
|
+
You should use `@seamless-auth/core` if:
|
|
40
|
+
|
|
41
|
+
- You are building a backend adapter
|
|
42
|
+
- You want full control over your HTTP layer
|
|
43
|
+
- You are integrating Seamless Auth into a non-Express runtime
|
|
44
|
+
- You want to audit or extend authentication behavior
|
|
45
|
+
|
|
46
|
+
If you are using Express, you probably want:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
@seamless-auth/express
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Design Principles
|
|
55
|
+
|
|
56
|
+
- **Explicit trust boundaries**
|
|
57
|
+
Browser cookies are never forwarded upstream.
|
|
58
|
+
|
|
59
|
+
- **Stateless by default**
|
|
60
|
+
All session data is encoded and signed.
|
|
61
|
+
|
|
62
|
+
- **Short-lived assertions**
|
|
63
|
+
Service tokens are minimal and ephemeral.
|
|
64
|
+
|
|
65
|
+
- **No hidden magic**
|
|
66
|
+
All inputs are explicit.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Core Concepts
|
|
71
|
+
|
|
72
|
+
### Identity States
|
|
73
|
+
|
|
74
|
+
- **Unauthenticated**
|
|
75
|
+
- **Pre-authenticated** (OTP / WebAuthn in progress)
|
|
76
|
+
- **Authenticated** (access cookie issued)
|
|
77
|
+
|
|
78
|
+
Core helpers enforce transitions between these states.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Public API (Overview)
|
|
83
|
+
|
|
84
|
+
Key exports include:
|
|
85
|
+
|
|
86
|
+
- `ensureCookies(...)` – validates and refreshes session cookies
|
|
87
|
+
- `refreshAccessToken(...)` – rotates expired access sessions
|
|
88
|
+
- `verifyCookieJwt(...)` – verifies signed cookie payloads
|
|
89
|
+
- `createServiceToken(...)` – creates short-lived M2M assertions
|
|
90
|
+
|
|
91
|
+
These functions return **descriptive results**, not HTTP responses.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Example (Adapter Pseudocode)
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const result = await ensureCookies(
|
|
99
|
+
{ path, cookies },
|
|
100
|
+
{
|
|
101
|
+
authServerUrl,
|
|
102
|
+
cookieSecret,
|
|
103
|
+
serviceSecret,
|
|
104
|
+
issuer,
|
|
105
|
+
audience,
|
|
106
|
+
keyId,
|
|
107
|
+
accessCookieName,
|
|
108
|
+
refreshCookieName,
|
|
109
|
+
preAuthCookieName,
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
if (result.setCookies) {
|
|
114
|
+
// adapter applies cookies
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (result.type === "error") {
|
|
118
|
+
// adapter sends HTTP error
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Testing
|
|
125
|
+
|
|
126
|
+
All logic in this package is tested against compiled output (`dist/`),
|
|
127
|
+
ensuring behavior matches production runtime exactly.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
**AGPL-3.0-only** © 2026 Fells Code LLC
|
|
134
|
+
|
|
135
|
+
This license ensures:
|
|
136
|
+
|
|
137
|
+
- transparency of security-critical code
|
|
138
|
+
- freedom to self-host and modify
|
|
139
|
+
- sustainability of the managed service offering
|
|
140
|
+
|
|
141
|
+
See [`LICENSE`](./LICENSE) for details.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface AuthFetchOptions {
|
|
2
|
+
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
3
|
+
headers?: Record<string, string>;
|
|
4
|
+
body?: unknown;
|
|
5
|
+
authorization?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function authFetch(url: string, options: AuthFetchOptions): Promise<Response>;
|
|
8
|
+
//# sourceMappingURL=authFetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authFetch.d.ts","sourceRoot":"","sources":["../src/authFetch.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC,CAYnB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export async function authFetch(url, options) {
|
|
2
|
+
const headers = {
|
|
3
|
+
"Content-Type": "application/json",
|
|
4
|
+
...options.headers,
|
|
5
|
+
...(options.authorization ? { Authorization: options.authorization } : {}),
|
|
6
|
+
};
|
|
7
|
+
return fetch(url, {
|
|
8
|
+
method: options.method,
|
|
9
|
+
headers,
|
|
10
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=authFetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authFetch.js","sourceRoot":"","sources":["../src/authFetch.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,OAAyB;IAEzB,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,OAAO,CAAC,OAAO;QAClB,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC;IAEF,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO;QACP,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9D,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ServiceTokenOptions {
|
|
2
|
+
issuer: string;
|
|
3
|
+
audience: string;
|
|
4
|
+
subject: string;
|
|
5
|
+
refreshToken?: string;
|
|
6
|
+
serviceSecret: string;
|
|
7
|
+
keyId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createServiceToken(opts: ServiceTokenOptions): string;
|
|
10
|
+
//# sourceMappingURL=createServiceToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createServiceToken.d.ts","sourceRoot":"","sources":["../src/createServiceToken.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAgBpE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
export function createServiceToken(opts) {
|
|
3
|
+
return jwt.sign({
|
|
4
|
+
iss: opts.issuer,
|
|
5
|
+
aud: opts.audience,
|
|
6
|
+
sub: opts.subject,
|
|
7
|
+
refreshToken: opts.refreshToken,
|
|
8
|
+
iat: Math.floor(Date.now() / 1000),
|
|
9
|
+
}, opts.serviceSecret, {
|
|
10
|
+
expiresIn: "60s",
|
|
11
|
+
algorithm: "HS256",
|
|
12
|
+
keyid: opts.keyId,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=createServiceToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createServiceToken.js","sourceRoot":"","sources":["../src/createServiceToken.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAW/B,MAAM,UAAU,kBAAkB,CAAC,IAAyB;IAC1D,OAAO,GAAG,CAAC,IAAI,CACb;QACE,GAAG,EAAE,IAAI,CAAC,MAAM;QAChB,GAAG,EAAE,IAAI,CAAC,QAAQ;QAClB,GAAG,EAAE,IAAI,CAAC,OAAO;QACjB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;KACnC,EACD,IAAI,CAAC,aAAa,EAClB;QACE,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,OAAO;QAClB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface EnsureCookiesInput {
|
|
2
|
+
path: string;
|
|
3
|
+
cookies: Record<string, string | undefined>;
|
|
4
|
+
}
|
|
5
|
+
export interface CookiePayload {
|
|
6
|
+
sub: string;
|
|
7
|
+
token?: string;
|
|
8
|
+
refreshToken?: string;
|
|
9
|
+
roles?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface CookieInstruction {
|
|
12
|
+
name: string;
|
|
13
|
+
value: CookiePayload;
|
|
14
|
+
ttl: number;
|
|
15
|
+
domain?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface EnsureCookiesResult {
|
|
18
|
+
type: "ok" | "error";
|
|
19
|
+
status?: number;
|
|
20
|
+
error?: string;
|
|
21
|
+
user?: {
|
|
22
|
+
sub: string;
|
|
23
|
+
roles?: string[];
|
|
24
|
+
};
|
|
25
|
+
setCookies?: CookieInstruction[];
|
|
26
|
+
clearCookies?: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface EnsureCookiesOptions {
|
|
29
|
+
authServerUrl: string;
|
|
30
|
+
cookieDomain?: string;
|
|
31
|
+
accessCookieName: string;
|
|
32
|
+
registrationCookieName: string;
|
|
33
|
+
refreshCookieName: string;
|
|
34
|
+
preAuthCookieName: string;
|
|
35
|
+
cookieSecret: string;
|
|
36
|
+
serviceSecret: string;
|
|
37
|
+
issuer: string;
|
|
38
|
+
audience: string;
|
|
39
|
+
keyId: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function ensureCookies(input: EnsureCookiesInput, opts: EnsureCookiesOptions): Promise<EnsureCookiesResult>;
|
|
42
|
+
//# sourceMappingURL=ensureCookies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensureCookies.d.ts","sourceRoot":"","sources":["../src/ensureCookies.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,aAAa,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE;QACL,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AA4BD,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,EACzB,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAsG9B"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { verifyCookieJwt } from "./verifyCookieJwt.js";
|
|
2
|
+
import { refreshAccessToken } from "./refreshAccessToken.js";
|
|
3
|
+
const COOKIE_REQUIREMENTS = {
|
|
4
|
+
"/webAuthn/login/finish": { name: "preAuthCookieName", required: true },
|
|
5
|
+
"/webAuthn/login/start": { name: "preAuthCookieName", required: true },
|
|
6
|
+
"/webAuthn/register/start": {
|
|
7
|
+
name: "registrationCookieName",
|
|
8
|
+
required: true,
|
|
9
|
+
},
|
|
10
|
+
"/webAuthn/register/finish": {
|
|
11
|
+
name: "registrationCookieName",
|
|
12
|
+
required: true,
|
|
13
|
+
},
|
|
14
|
+
"/otp/verify-email-otp": {
|
|
15
|
+
name: "registrationCookieName",
|
|
16
|
+
required: true,
|
|
17
|
+
},
|
|
18
|
+
"/otp/verify-phone-otp": {
|
|
19
|
+
name: "registrationCookieName",
|
|
20
|
+
required: true,
|
|
21
|
+
},
|
|
22
|
+
"/logout": { name: "accessCookieName", required: true },
|
|
23
|
+
"/users/me": { name: "accessCookieName", required: true },
|
|
24
|
+
};
|
|
25
|
+
export async function ensureCookies(input, opts) {
|
|
26
|
+
const match = Object.entries(COOKIE_REQUIREMENTS).find(([path]) => input.path.startsWith(path));
|
|
27
|
+
if (!match) {
|
|
28
|
+
return { type: "ok" };
|
|
29
|
+
}
|
|
30
|
+
const [, { name, required }] = match;
|
|
31
|
+
const cookieName = opts[name];
|
|
32
|
+
if (!cookieName) {
|
|
33
|
+
return {
|
|
34
|
+
type: "error",
|
|
35
|
+
status: 400,
|
|
36
|
+
error: "Missing required cookie",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const cookieValue = input.cookies[cookieName];
|
|
40
|
+
const refreshCookie = input.cookies[opts.refreshCookieName];
|
|
41
|
+
if (required && !cookieValue) {
|
|
42
|
+
if (!refreshCookie) {
|
|
43
|
+
return {
|
|
44
|
+
type: "error",
|
|
45
|
+
status: 400,
|
|
46
|
+
error: `Missing required cookie "${cookieName}"`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const refreshed = await refreshAccessToken(refreshCookie, {
|
|
50
|
+
authServerUrl: opts.authServerUrl,
|
|
51
|
+
cookieSecret: opts.cookieSecret,
|
|
52
|
+
serviceSecret: opts.serviceSecret,
|
|
53
|
+
issuer: opts.issuer,
|
|
54
|
+
audience: opts.audience,
|
|
55
|
+
keyId: opts.keyId,
|
|
56
|
+
});
|
|
57
|
+
if (!refreshed?.token) {
|
|
58
|
+
return {
|
|
59
|
+
type: "error",
|
|
60
|
+
status: 401,
|
|
61
|
+
error: "Refresh failed",
|
|
62
|
+
clearCookies: [
|
|
63
|
+
cookieName,
|
|
64
|
+
opts.registrationCookieName,
|
|
65
|
+
opts.refreshCookieName,
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
type: "ok",
|
|
71
|
+
user: {
|
|
72
|
+
sub: refreshed.sub,
|
|
73
|
+
roles: refreshed.roles,
|
|
74
|
+
},
|
|
75
|
+
setCookies: [
|
|
76
|
+
{
|
|
77
|
+
name: cookieName,
|
|
78
|
+
value: {
|
|
79
|
+
sub: refreshed.sub,
|
|
80
|
+
roles: refreshed.roles,
|
|
81
|
+
},
|
|
82
|
+
ttl: refreshed.ttl,
|
|
83
|
+
domain: opts.cookieDomain,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: opts.refreshCookieName,
|
|
87
|
+
value: {
|
|
88
|
+
sub: refreshed.sub,
|
|
89
|
+
refreshToken: refreshed.refreshToken,
|
|
90
|
+
},
|
|
91
|
+
ttl: refreshed.refreshTtl,
|
|
92
|
+
domain: opts.cookieDomain,
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (cookieValue) {
|
|
98
|
+
const payload = verifyCookieJwt(cookieValue, opts.cookieSecret);
|
|
99
|
+
if (!payload) {
|
|
100
|
+
return {
|
|
101
|
+
type: "error",
|
|
102
|
+
status: 401,
|
|
103
|
+
error: `Invalid or expired ${cookieName} cookie`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
type: "ok",
|
|
108
|
+
user: {
|
|
109
|
+
sub: payload.sub,
|
|
110
|
+
roles: payload.roles,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return { type: "ok" };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=ensureCookies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensureCookies.js","sourceRoot":"","sources":["../src/ensureCookies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface GetSeamlessUserOptions {
|
|
2
|
+
authServerUrl: string;
|
|
3
|
+
cookieSecret: string;
|
|
4
|
+
cookieName?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getSeamlessUser<T = any>(cookies: Record<string, string | undefined>, opts: GetSeamlessUserOptions): Promise<T | null>;
|
|
7
|
+
//# sourceMappingURL=getSeamlessUser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSeamlessUser.d.ts","sourceRoot":"","sources":["../src/getSeamlessUser.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,eAAe,CAAC,CAAC,GAAG,GAAG,EAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAiBnB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { authFetch } from "./authFetch.js";
|
|
2
|
+
import { verifyCookieJwt } from "./verifyCookieJwt.js";
|
|
3
|
+
export async function getSeamlessUser(cookies, opts) {
|
|
4
|
+
const cookieName = opts.cookieName ?? "seamless-access";
|
|
5
|
+
const token = cookies[cookieName];
|
|
6
|
+
if (!token)
|
|
7
|
+
return null;
|
|
8
|
+
const payload = verifyCookieJwt(token, opts.cookieSecret);
|
|
9
|
+
if (!payload)
|
|
10
|
+
return null;
|
|
11
|
+
const response = await authFetch(`${opts.authServerUrl}/users/me`, {
|
|
12
|
+
method: "GET",
|
|
13
|
+
});
|
|
14
|
+
if (!response.ok)
|
|
15
|
+
return null;
|
|
16
|
+
const data = await response.json();
|
|
17
|
+
return data.user ?? null;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=getSeamlessUser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSeamlessUser.js","sourceRoot":"","sources":["../src/getSeamlessUser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAQvD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA2C,EAC3C,IAA4B;IAE5B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,iBAAiB,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAElC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,WAAW,EAAE;QACjE,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE9B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CookiePayload } from "../ensureCookies.js";
|
|
2
|
+
export interface FinishLoginInput {
|
|
3
|
+
body: unknown;
|
|
4
|
+
authorization?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FinishLoginOptions {
|
|
7
|
+
authServerUrl: string;
|
|
8
|
+
cookieDomain?: string;
|
|
9
|
+
accessCookieName: string;
|
|
10
|
+
refreshCookieName: string;
|
|
11
|
+
}
|
|
12
|
+
export interface FinishLoginResult {
|
|
13
|
+
status: number;
|
|
14
|
+
body?: unknown;
|
|
15
|
+
error?: string;
|
|
16
|
+
setCookies?: {
|
|
17
|
+
name: string;
|
|
18
|
+
value: CookiePayload;
|
|
19
|
+
ttl: number;
|
|
20
|
+
domain?: string;
|
|
21
|
+
}[];
|
|
22
|
+
}
|
|
23
|
+
export declare function finishLoginHandler(input: FinishLoginInput, opts: FinishLoginOptions): Promise<FinishLoginResult>;
|
|
24
|
+
//# sourceMappingURL=finishLogin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finishLogin.d.ts","sourceRoot":"","sources":["../../src/handlers/finishLogin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,EAAE,CAAC;CACL;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,iBAAiB,CAAC,CAqD5B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { authFetch } from "../authFetch.js";
|
|
2
|
+
import { verifySignedAuthResponse } from "../verifySignedAuthResponse.js";
|
|
3
|
+
export async function finishLoginHandler(input, opts) {
|
|
4
|
+
const up = await authFetch(`${opts.authServerUrl}/webAuthn/login/finish`, {
|
|
5
|
+
method: "POST",
|
|
6
|
+
body: input.body,
|
|
7
|
+
authorization: input.authorization,
|
|
8
|
+
});
|
|
9
|
+
const data = await up.json();
|
|
10
|
+
if (!up.ok) {
|
|
11
|
+
return {
|
|
12
|
+
status: up.status,
|
|
13
|
+
error: data,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const verifiedAccessToken = await verifySignedAuthResponse(data.token, opts.authServerUrl);
|
|
17
|
+
if (!verifiedAccessToken) {
|
|
18
|
+
throw new Error("Invalid signed response from Auth Server");
|
|
19
|
+
}
|
|
20
|
+
if (verifiedAccessToken.sub !== data.sub) {
|
|
21
|
+
throw new Error("Signature mismatch with data payload");
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
status: 200,
|
|
25
|
+
body: data,
|
|
26
|
+
setCookies: [
|
|
27
|
+
{
|
|
28
|
+
name: opts.accessCookieName,
|
|
29
|
+
value: {
|
|
30
|
+
sub: data.sub,
|
|
31
|
+
roles: data.roles,
|
|
32
|
+
},
|
|
33
|
+
ttl: data.ttl,
|
|
34
|
+
domain: opts.cookieDomain,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: opts.refreshCookieName,
|
|
38
|
+
value: {
|
|
39
|
+
sub: data.sub,
|
|
40
|
+
refreshToken: data.refreshToken,
|
|
41
|
+
},
|
|
42
|
+
ttl: data.refreshTtl,
|
|
43
|
+
domain: opts.cookieDomain,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=finishLogin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finishLogin.js","sourceRoot":"","sources":["../../src/handlers/finishLogin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AA0B1E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAuB,EACvB,IAAwB;IAExB,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,wBAAwB,EAAE;QACxE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACX,OAAO;YACL,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,mBAAmB,GAAG,MAAM,wBAAwB,CACxD,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,aAAa,CACnB,CAAC;IAEF,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,mBAAmB,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,IAAI;QACV,UAAU,EAAE;YACV;gBACE,IAAI,EAAE,IAAI,CAAC,gBAAgB;gBAC3B,KAAK,EAAE;oBACL,GAAG,EAAE,IAAI,CAAC,GAAG;oBACb,KAAK,EAAE,IAAI,CAAC,KAAK;iBAClB;gBACD,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,MAAM,EAAE,IAAI,CAAC,YAAY;aAC1B;YACD;gBACE,IAAI,EAAE,IAAI,CAAC,iBAAiB;gBAC5B,KAAK,EAAE;oBACL,GAAG,EAAE,IAAI,CAAC,GAAG;oBACb,YAAY,EAAE,IAAI,CAAC,YAAY;iBAChC;gBACD,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,MAAM,EAAE,IAAI,CAAC,YAAY;aAC1B;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CookiePayload } from "../ensureCookies.js";
|
|
2
|
+
export interface FinishRegisterInput {
|
|
3
|
+
authorization?: string;
|
|
4
|
+
body: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface FinishRegisterOptions {
|
|
7
|
+
authServerUrl: string;
|
|
8
|
+
cookieDomain?: string;
|
|
9
|
+
accessCookieName: string;
|
|
10
|
+
refreshCookieName: string;
|
|
11
|
+
}
|
|
12
|
+
export interface FinishRegisterResult {
|
|
13
|
+
status: number;
|
|
14
|
+
error?: unknown;
|
|
15
|
+
setCookies?: {
|
|
16
|
+
name: string;
|
|
17
|
+
value: CookiePayload;
|
|
18
|
+
ttl: number;
|
|
19
|
+
domain?: string;
|
|
20
|
+
}[];
|
|
21
|
+
}
|
|
22
|
+
export declare function finishRegisterHandler(input: FinishRegisterInput, opts: FinishRegisterOptions): Promise<FinishRegisterResult>;
|
|
23
|
+
//# sourceMappingURL=finishRegister.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finishRegister.d.ts","sourceRoot":"","sources":["../../src/handlers/finishRegister.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,EAAE,CAAC;CACL;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,mBAAmB,EAC1B,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,oBAAoB,CAAC,CAoD/B"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { authFetch } from "../authFetch.js";
|
|
2
|
+
import { verifySignedAuthResponse } from "../verifySignedAuthResponse.js";
|
|
3
|
+
export async function finishRegisterHandler(input, opts) {
|
|
4
|
+
const up = await authFetch(`${opts.authServerUrl}/webAuthn/register/finish`, {
|
|
5
|
+
method: "POST",
|
|
6
|
+
body: input.body,
|
|
7
|
+
authorization: input.authorization,
|
|
8
|
+
});
|
|
9
|
+
const data = await up.json();
|
|
10
|
+
if (!up.ok) {
|
|
11
|
+
return {
|
|
12
|
+
status: up.status,
|
|
13
|
+
error: data,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const verified = await verifySignedAuthResponse(data.token, opts.authServerUrl);
|
|
17
|
+
if (!verified) {
|
|
18
|
+
throw new Error("Invalid signed response from Auth Server");
|
|
19
|
+
}
|
|
20
|
+
if (verified.sub !== data.sub) {
|
|
21
|
+
throw new Error("Signature mismatch with data payload");
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
status: 204,
|
|
25
|
+
setCookies: [
|
|
26
|
+
{
|
|
27
|
+
name: opts.accessCookieName,
|
|
28
|
+
value: {
|
|
29
|
+
sub: data.sub,
|
|
30
|
+
roles: data.roles,
|
|
31
|
+
},
|
|
32
|
+
ttl: data.ttl,
|
|
33
|
+
domain: opts.cookieDomain,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: opts.refreshCookieName,
|
|
37
|
+
value: {
|
|
38
|
+
sub: data.sub,
|
|
39
|
+
refreshToken: data.refreshToken,
|
|
40
|
+
},
|
|
41
|
+
ttl: data.refreshTtl,
|
|
42
|
+
domain: opts.cookieDomain,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=finishRegister.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finishRegister.js","sourceRoot":"","sources":["../../src/handlers/finishRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAyB1E,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAA0B,EAC1B,IAA2B;IAE3B,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,2BAA2B,EAAE;QAC3E,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACX,OAAO;YACL,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAC7C,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,aAAa,CACnB,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG;QACX,UAAU,EAAE;YACV;gBACE,IAAI,EAAE,IAAI,CAAC,gBAAgB;gBAC3B,KAAK,EAAE;oBACL,GAAG,EAAE,IAAI,CAAC,GAAG;oBACb,KAAK,EAAE,IAAI,CAAC,KAAK;iBAClB;gBACD,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,MAAM,EAAE,IAAI,CAAC,YAAY;aAC1B;YACD;gBACE,IAAI,EAAE,IAAI,CAAC,iBAAiB;gBAC5B,KAAK,EAAE;oBACL,GAAG,EAAE,IAAI,CAAC,GAAG;oBACb,YAAY,EAAE,IAAI,CAAC,YAAY;iBAChC;gBACD,GAAG,EAAE,IAAI,CAAC,UAAU;gBACpB,MAAM,EAAE,IAAI,CAAC,YAAY;aAC1B;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CookiePayload } from "../ensureCookies.js";
|
|
2
|
+
export interface LoginInput {
|
|
3
|
+
body: unknown;
|
|
4
|
+
}
|
|
5
|
+
export interface LoginOptions {
|
|
6
|
+
authServerUrl: string;
|
|
7
|
+
cookieDomain?: string;
|
|
8
|
+
preAuthCookieName: string;
|
|
9
|
+
}
|
|
10
|
+
export interface LoginResult {
|
|
11
|
+
status: number;
|
|
12
|
+
error?: string;
|
|
13
|
+
setCookies?: {
|
|
14
|
+
name: string;
|
|
15
|
+
value: CookiePayload;
|
|
16
|
+
ttl: number;
|
|
17
|
+
domain?: string;
|
|
18
|
+
}[];
|
|
19
|
+
}
|
|
20
|
+
export declare function loginHandler(input: LoginInput, opts: LoginOptions): Promise<LoginResult>;
|
|
21
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/handlers/login.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,EAAE,CAAC;CACL;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,WAAW,CAAC,CAuCtB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { authFetch } from "../authFetch.js";
|
|
2
|
+
import { verifySignedAuthResponse } from "../verifySignedAuthResponse.js";
|
|
3
|
+
export async function loginHandler(input, opts) {
|
|
4
|
+
const up = await authFetch(`${opts.authServerUrl}/login`, {
|
|
5
|
+
method: "POST",
|
|
6
|
+
body: input.body,
|
|
7
|
+
});
|
|
8
|
+
const data = await up.json();
|
|
9
|
+
if (!up.ok) {
|
|
10
|
+
return {
|
|
11
|
+
status: up.status,
|
|
12
|
+
error: data,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const verified = await verifySignedAuthResponse(data.token, opts.authServerUrl);
|
|
16
|
+
if (!verified) {
|
|
17
|
+
throw new Error("Invalid signed response from Auth Server");
|
|
18
|
+
}
|
|
19
|
+
if (verified.sub !== data.sub) {
|
|
20
|
+
throw new Error("Signature mismatch with data payload");
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
status: 204,
|
|
24
|
+
setCookies: [
|
|
25
|
+
{
|
|
26
|
+
name: opts.preAuthCookieName,
|
|
27
|
+
value: { sub: data.sub, token: data.token },
|
|
28
|
+
ttl: data.ttl,
|
|
29
|
+
domain: opts.cookieDomain,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/handlers/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAuB1E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAiB,EACjB,IAAkB;IAElB,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,QAAQ,EAAE;QACxD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACX,OAAO;YACL,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAC7C,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,aAAa,CACnB,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG;QACX,UAAU,EAAE;YACV;gBACE,IAAI,EAAE,IAAI,CAAC,iBAAiB;gBAC5B,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;gBAC3C,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,MAAM,EAAE,IAAI,CAAC,YAAY;aAC1B;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface LogoutOptions {
|
|
2
|
+
authServerUrl: string;
|
|
3
|
+
accessCookieName: string;
|
|
4
|
+
registrationCookieName: string;
|
|
5
|
+
refreshCookieName: string;
|
|
6
|
+
}
|
|
7
|
+
export interface LogoutResult {
|
|
8
|
+
status: number;
|
|
9
|
+
clearCookies: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function logoutHandler(opts: LogoutOptions): Promise<LogoutResult>;
|
|
12
|
+
//# sourceMappingURL=logout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/handlers/logout.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,YAAY,CAAC,CAavB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { authFetch } from "../authFetch.js";
|
|
2
|
+
export async function logoutHandler(opts) {
|
|
3
|
+
await authFetch(`${opts.authServerUrl}/logout`, {
|
|
4
|
+
method: "GET",
|
|
5
|
+
});
|
|
6
|
+
return {
|
|
7
|
+
status: 204,
|
|
8
|
+
clearCookies: [
|
|
9
|
+
opts.accessCookieName,
|
|
10
|
+
opts.registrationCookieName,
|
|
11
|
+
opts.refreshCookieName,
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/handlers/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAc5C,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAmB;IAEnB,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,SAAS,EAAE;QAC9C,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,GAAG;QACX,YAAY,EAAE;YACZ,IAAI,CAAC,gBAAgB;YACrB,IAAI,CAAC,sBAAsB;YAC3B,IAAI,CAAC,iBAAiB;SACvB;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface MeOptions {
|
|
2
|
+
authServerUrl: string;
|
|
3
|
+
preAuthCookieName: string;
|
|
4
|
+
authorization?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface MeResult {
|
|
7
|
+
status: number;
|
|
8
|
+
body?: {
|
|
9
|
+
user: unknown;
|
|
10
|
+
credentials?: unknown;
|
|
11
|
+
};
|
|
12
|
+
error?: string;
|
|
13
|
+
clearCookies?: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function meHandler(opts: MeOptions): Promise<MeResult>;
|
|
16
|
+
//# sourceMappingURL=me.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"me.d.ts","sourceRoot":"","sources":["../../src/handlers/me.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,OAAO,CAAC;QACd,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyBlE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { authFetch } from "../authFetch.js";
|
|
2
|
+
export async function meHandler(opts) {
|
|
3
|
+
const up = await authFetch(`${opts.authServerUrl}/users/me`, {
|
|
4
|
+
method: "GET",
|
|
5
|
+
authorization: opts.authorization,
|
|
6
|
+
});
|
|
7
|
+
const data = await up.json();
|
|
8
|
+
const clearCookies = [opts.preAuthCookieName];
|
|
9
|
+
if (!data?.user) {
|
|
10
|
+
return {
|
|
11
|
+
status: 401,
|
|
12
|
+
error: "unauthenticated",
|
|
13
|
+
clearCookies,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
status: 200,
|
|
18
|
+
body: {
|
|
19
|
+
user: data.user,
|
|
20
|
+
credentials: data.credentials,
|
|
21
|
+
},
|
|
22
|
+
clearCookies,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=me.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"me.js","sourceRoot":"","sources":["../../src/handlers/me.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAkB5C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAe;IAC7C,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,WAAW,EAAE;QAC3D,MAAM,EAAE,KAAK;QACb,aAAa,EAAE,IAAI,CAAC,aAAa;KAClC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAE9C,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QAChB,OAAO;YACL,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,iBAAiB;YACxB,YAAY;SACb,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B;QACD,YAAY;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CookiePayload } from "../ensureCookies.js";
|
|
2
|
+
export interface RegisterInput {
|
|
3
|
+
body: unknown;
|
|
4
|
+
}
|
|
5
|
+
export interface RegisterOptions {
|
|
6
|
+
authServerUrl: string;
|
|
7
|
+
cookieDomain?: string;
|
|
8
|
+
registrationCookieName: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RegisterResult {
|
|
11
|
+
status: number;
|
|
12
|
+
body?: unknown;
|
|
13
|
+
error?: unknown;
|
|
14
|
+
setCookies?: {
|
|
15
|
+
name: string;
|
|
16
|
+
value: CookiePayload;
|
|
17
|
+
ttl: number;
|
|
18
|
+
domain?: string;
|
|
19
|
+
}[];
|
|
20
|
+
}
|
|
21
|
+
export declare function registerHandler(input: RegisterInput, opts: RegisterOptions): Promise<RegisterResult>;
|
|
22
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/handlers/register.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,EAAE,CAAC;CACL;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,cAAc,CAAC,CA2BzB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { authFetch } from "../authFetch.js";
|
|
2
|
+
export async function registerHandler(input, opts) {
|
|
3
|
+
const up = await authFetch(`${opts.authServerUrl}/registration/register`, {
|
|
4
|
+
method: "POST",
|
|
5
|
+
body: input.body,
|
|
6
|
+
});
|
|
7
|
+
const data = await up.json();
|
|
8
|
+
if (!up.ok) {
|
|
9
|
+
return {
|
|
10
|
+
status: up.status,
|
|
11
|
+
error: data,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
status: 200,
|
|
16
|
+
body: data,
|
|
17
|
+
setCookies: [
|
|
18
|
+
{
|
|
19
|
+
name: opts.registrationCookieName,
|
|
20
|
+
value: { sub: data.sub },
|
|
21
|
+
ttl: data.ttl,
|
|
22
|
+
domain: opts.cookieDomain,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/handlers/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAyB5C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAoB,EACpB,IAAqB;IAErB,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,wBAAwB,EAAE;QACxE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACX,OAAO;YACL,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,IAAI;QACV,UAAU,EAAE;YACV;gBACE,IAAI,EAAE,IAAI,CAAC,sBAAsB;gBACjC,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;gBACxB,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,MAAM,EAAE,IAAI,CAAC,YAAY;aAC1B;SACF;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "./authFetch.js";
|
|
2
|
+
export * from "./ensureCookies.js";
|
|
3
|
+
export * from "./verifyCookieJwt.js";
|
|
4
|
+
export * from "./refreshAccessToken.js";
|
|
5
|
+
export * from "./getSeamlessUser.js";
|
|
6
|
+
export * from "./createServiceToken.js";
|
|
7
|
+
export * from "./handlers/login.js";
|
|
8
|
+
export * from "./handlers/finishLogin.js";
|
|
9
|
+
export * from "./handlers/register.js";
|
|
10
|
+
export * from "./handlers/finishRegister.js";
|
|
11
|
+
export * from "./handlers/logout.js";
|
|
12
|
+
export * from "./handlers/me.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AAExC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "./authFetch.js";
|
|
2
|
+
export * from "./ensureCookies.js";
|
|
3
|
+
export * from "./verifyCookieJwt.js";
|
|
4
|
+
export * from "./refreshAccessToken.js";
|
|
5
|
+
export * from "./getSeamlessUser.js";
|
|
6
|
+
export * from "./createServiceToken.js";
|
|
7
|
+
export * from "./handlers/login.js";
|
|
8
|
+
export * from "./handlers/finishLogin.js";
|
|
9
|
+
export * from "./handlers/register.js";
|
|
10
|
+
export * from "./handlers/finishRegister.js";
|
|
11
|
+
export * from "./handlers/logout.js";
|
|
12
|
+
export * from "./handlers/me.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AAExC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface RefreshAccessTokenOptions {
|
|
2
|
+
authServerUrl: string;
|
|
3
|
+
cookieSecret: string;
|
|
4
|
+
serviceSecret: string;
|
|
5
|
+
issuer: string;
|
|
6
|
+
audience: string;
|
|
7
|
+
keyId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function refreshAccessToken(refreshCookie: string, opts: RefreshAccessTokenOptions): Promise<{
|
|
10
|
+
sub: string;
|
|
11
|
+
token: string;
|
|
12
|
+
refreshToken: string;
|
|
13
|
+
roles: string[];
|
|
14
|
+
ttl: number;
|
|
15
|
+
refreshTtl: number;
|
|
16
|
+
} | null>;
|
|
17
|
+
//# sourceMappingURL=refreshAccessToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refreshAccessToken.d.ts","sourceRoot":"","sources":["../src/refreshAccessToken.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC;IACT,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAAC,CAuBR"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { authFetch } from "./authFetch.js";
|
|
2
|
+
import { verifyRefreshCookie } from "./verifyRefreshCookie.js";
|
|
3
|
+
import { createServiceToken } from "./createServiceToken.js";
|
|
4
|
+
export async function refreshAccessToken(refreshCookie, opts) {
|
|
5
|
+
const payload = verifyRefreshCookie(refreshCookie, opts.cookieSecret);
|
|
6
|
+
if (!payload)
|
|
7
|
+
return null;
|
|
8
|
+
const serviceToken = createServiceToken({
|
|
9
|
+
issuer: opts.issuer,
|
|
10
|
+
audience: opts.audience,
|
|
11
|
+
subject: payload.sub,
|
|
12
|
+
refreshToken: payload.refreshToken,
|
|
13
|
+
serviceSecret: opts.serviceSecret,
|
|
14
|
+
keyId: opts.keyId,
|
|
15
|
+
});
|
|
16
|
+
const response = await authFetch(`${opts.authServerUrl}/refresh`, {
|
|
17
|
+
method: "GET",
|
|
18
|
+
headers: {
|
|
19
|
+
Authorization: `Bearer ${serviceToken}`,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok)
|
|
23
|
+
return null;
|
|
24
|
+
return response.json();
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=refreshAccessToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refreshAccessToken.js","sourceRoot":"","sources":["../src/refreshAccessToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAW7D,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,aAAqB,EACrB,IAA+B;IAS/B,MAAM,OAAO,GAAG,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACtE,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,YAAY,GAAG,kBAAkB,CAAC;QACtC,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,OAAO,EAAE,OAAO,CAAC,GAAG;QACpB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,UAAU,EAAE;QAChE,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,YAAY,EAAE;SACxC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyCookieJwt.d.ts","sourceRoot":"","sources":["../src/verifyCookieJwt.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEpD,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EAC/D,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,CAAC,GAAG,IAAI,CASV"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import jwt, {} from "jsonwebtoken";
|
|
2
|
+
export function verifyCookieJwt(token, secret) {
|
|
3
|
+
try {
|
|
4
|
+
return jwt.verify(token, secret, {
|
|
5
|
+
algorithms: ["HS256"],
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
// Intentional no-op
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=verifyCookieJwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyCookieJwt.js","sourceRoot":"","sources":["../src/verifyCookieJwt.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,EAAE,EAAmB,MAAM,cAAc,CAAC;AAEpD,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,MAAc;IAEd,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE;YAC/B,UAAU,EAAE,CAAC,OAAO,CAAC;SACtB,CAAM,CAAC;IACV,CAAC;IAAC,MAAM,CAAC;QACP,oBAAoB;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type JwtPayload } from "jsonwebtoken";
|
|
2
|
+
export interface RefreshCookiePayload extends JwtPayload {
|
|
3
|
+
sub: string;
|
|
4
|
+
refreshToken: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function verifyRefreshCookie(token: string, cookieSecret: string): RefreshCookiePayload | null;
|
|
7
|
+
//# sourceMappingURL=verifyRefreshCookie.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyRefreshCookie.d.ts","sourceRoot":"","sources":["../src/verifyRefreshCookie.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,GACnB,oBAAoB,GAAG,IAAI,CAQ7B"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import jwt, {} from "jsonwebtoken";
|
|
2
|
+
export function verifyRefreshCookie(token, cookieSecret) {
|
|
3
|
+
try {
|
|
4
|
+
return jwt.verify(token, cookieSecret, {
|
|
5
|
+
algorithms: ["HS256"],
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=verifyRefreshCookie.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyRefreshCookie.js","sourceRoot":"","sources":["../src/verifyRefreshCookie.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,EAAE,EAAmB,MAAM,cAAc,CAAC;AAOpD,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,YAAoB;IAEpB,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE;YACrC,UAAU,EAAE,CAAC,OAAO,CAAC;SACtB,CAAyB,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifySignedAuthResponse.d.ts","sourceRoot":"","sources":["../src/verifySignedAuthResponse.ts"],"names":[],"mappings":"AAEA,wBAAsB,wBAAwB,CAAC,CAAC,GAAG,GAAG,EACpD,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAenB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
2
|
+
export async function verifySignedAuthResponse(token, authServerUrl) {
|
|
3
|
+
try {
|
|
4
|
+
const jwksUrl = new URL("/.well-known/jwks.json", authServerUrl).toString();
|
|
5
|
+
const JWKS = createRemoteJWKSet(new URL(jwksUrl));
|
|
6
|
+
const { payload } = await jwtVerify(token, JWKS, {
|
|
7
|
+
algorithms: ["RS256"],
|
|
8
|
+
issuer: authServerUrl,
|
|
9
|
+
});
|
|
10
|
+
return payload;
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
console.error("[SeamlessAuth] Failed to verify signed auth response:", err);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=verifySignedAuthResponse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifySignedAuthResponse.js","sourceRoot":"","sources":["../src/verifySignedAuthResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAAa,EACb,aAAqB;IAErB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,wBAAwB,EAAE,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5E,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAElD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/C,UAAU,EAAE,CAAC,OAAO,CAAC;YACrB,MAAM,EAAE,aAAa;SACtB,CAAC,CAAC;QAEH,OAAO,OAAY,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,uDAAuD,EAAE,GAAG,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@seamless-auth/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Framework-agnostic core authentication logic for SeamlessAuth",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"author": "Fells Code, LLC",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"homepage": "https://seamlessauth.com",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/fells-code/seamless-auth-server/packages/core"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./handlers/*": {
|
|
22
|
+
"types": "./dist/handlers/*.d.ts",
|
|
23
|
+
"import": "./dist/handlers/*.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"LICENSE",
|
|
29
|
+
"LICENSE.md",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -p tsconfig.json",
|
|
37
|
+
"clean": "rm -rf dist",
|
|
38
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
39
|
+
"test": "npm run build && NODE_OPTIONS=--experimental-vm-modules jest",
|
|
40
|
+
"test:watch": "npm run build && NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"jose": "^6.1.3",
|
|
44
|
+
"jsonwebtoken": "^9.0.2"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/jest": "^29.5.14",
|
|
48
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
49
|
+
"jest": "^29.7.0",
|
|
50
|
+
"ts-node": "^10.9.2",
|
|
51
|
+
"typescript": "^5.9.3"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
}
|
|
56
|
+
}
|