@draftlab/auth 0.15.0 → 0.16.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/dist/esm/allow.js +26 -0
- package/dist/esm/client.js +254 -0
- package/dist/esm/core.js +597 -0
- package/dist/esm/css.d.js +0 -0
- package/dist/esm/error.js +88 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/keys.js +126 -0
- package/dist/esm/mutex.js +53 -0
- package/dist/esm/pkce.js +87 -0
- package/dist/esm/provider/apple.js +15 -0
- package/dist/esm/provider/code.js +62 -0
- package/dist/esm/provider/discord.js +15 -0
- package/dist/esm/provider/facebook.js +15 -0
- package/dist/esm/provider/github.js +15 -0
- package/dist/esm/provider/gitlab.js +15 -0
- package/dist/esm/provider/google.js +16 -0
- package/dist/esm/provider/linkedin.js +15 -0
- package/dist/esm/provider/magiclink.js +83 -0
- package/dist/esm/provider/microsoft.js +15 -0
- package/dist/esm/provider/oauth2.js +130 -0
- package/dist/esm/provider/password.js +331 -0
- package/dist/esm/provider/provider.js +18 -0
- package/dist/esm/provider/reddit.js +15 -0
- package/dist/esm/provider/slack.js +15 -0
- package/dist/esm/provider/spotify.js +15 -0
- package/dist/esm/provider/twitch.js +15 -0
- package/dist/esm/provider/vercel.js +17 -0
- package/dist/esm/random.js +40 -0
- package/dist/esm/revocation.js +27 -0
- package/dist/esm/storage/memory.js +110 -0
- package/dist/esm/storage/storage.js +56 -0
- package/dist/esm/storage/turso.js +93 -0
- package/dist/esm/storage/unstorage.js +78 -0
- package/dist/esm/subject.js +7 -0
- package/dist/esm/themes/theme.js +115 -0
- package/dist/esm/toolkit/client.js +119 -0
- package/dist/esm/toolkit/index.js +25 -0
- package/dist/esm/toolkit/providers/facebook.js +11 -0
- package/dist/esm/toolkit/providers/github.js +11 -0
- package/dist/esm/toolkit/providers/google.js +11 -0
- package/dist/esm/toolkit/providers/strategy.js +0 -0
- package/dist/esm/toolkit/storage.js +81 -0
- package/dist/esm/toolkit/utils.js +18 -0
- package/dist/esm/types.js +0 -0
- package/dist/esm/ui/base.js +478 -0
- package/dist/esm/ui/code.js +186 -0
- package/dist/esm/ui/form.js +46 -0
- package/dist/esm/ui/icon.js +242 -0
- package/dist/esm/ui/magiclink.js +158 -0
- package/dist/esm/ui/password.js +435 -0
- package/dist/esm/ui/select.js +102 -0
- package/dist/esm/util.js +59 -0
- package/dist/{allow.d.mts → types/allow.d.ts} +9 -11
- package/dist/types/allow.d.ts.map +1 -0
- package/dist/types/client.d.ts +462 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/core.d.ts +113 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/{error.d.mts → types/error.d.ts} +95 -97
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{keys.d.mts → types/keys.d.ts} +20 -24
- package/dist/types/keys.d.ts.map +1 -0
- package/dist/types/mutex.d.ts +42 -0
- package/dist/types/mutex.d.ts.map +1 -0
- package/dist/{pkce.d.mts → types/pkce.d.ts} +10 -11
- package/dist/types/pkce.d.ts.map +1 -0
- package/dist/types/provider/apple.d.ts +197 -0
- package/dist/types/provider/apple.d.ts.map +1 -0
- package/dist/types/provider/code.d.ts +288 -0
- package/dist/types/provider/code.d.ts.map +1 -0
- package/dist/types/provider/discord.d.ts +206 -0
- package/dist/types/provider/discord.d.ts.map +1 -0
- package/dist/types/provider/facebook.d.ts +200 -0
- package/dist/types/provider/facebook.d.ts.map +1 -0
- package/dist/types/provider/github.d.ts +220 -0
- package/dist/types/provider/github.d.ts.map +1 -0
- package/dist/types/provider/gitlab.d.ts +180 -0
- package/dist/types/provider/gitlab.d.ts.map +1 -0
- package/dist/types/provider/google.d.ts +158 -0
- package/dist/types/provider/google.d.ts.map +1 -0
- package/dist/types/provider/linkedin.d.ts +190 -0
- package/dist/types/provider/linkedin.d.ts.map +1 -0
- package/dist/types/provider/magiclink.d.ts +141 -0
- package/dist/types/provider/magiclink.d.ts.map +1 -0
- package/dist/types/provider/microsoft.d.ts +247 -0
- package/dist/types/provider/microsoft.d.ts.map +1 -0
- package/dist/types/provider/oauth2.d.ts +229 -0
- package/dist/types/provider/oauth2.d.ts.map +1 -0
- package/dist/types/provider/password.d.ts +408 -0
- package/dist/types/provider/password.d.ts.map +1 -0
- package/dist/types/provider/provider.d.ts +226 -0
- package/dist/types/provider/provider.d.ts.map +1 -0
- package/dist/types/provider/reddit.d.ts +159 -0
- package/dist/types/provider/reddit.d.ts.map +1 -0
- package/dist/types/provider/slack.d.ts +171 -0
- package/dist/types/provider/slack.d.ts.map +1 -0
- package/dist/types/provider/spotify.d.ts +168 -0
- package/dist/types/provider/spotify.d.ts.map +1 -0
- package/dist/types/provider/twitch.d.ts +163 -0
- package/dist/types/provider/twitch.d.ts.map +1 -0
- package/dist/types/provider/vercel.d.ts +294 -0
- package/dist/types/provider/vercel.d.ts.map +1 -0
- package/dist/{random.d.mts → types/random.d.ts} +4 -6
- package/dist/types/random.d.ts.map +1 -0
- package/dist/types/revocation.d.ts +76 -0
- package/dist/types/revocation.d.ts.map +1 -0
- package/dist/{storage/memory.d.mts → types/storage/memory.d.ts} +17 -21
- package/dist/types/storage/memory.d.ts.map +1 -0
- package/dist/types/storage/storage.d.ts +177 -0
- package/dist/types/storage/storage.d.ts.map +1 -0
- package/dist/{storage/turso.d.mts → types/storage/turso.d.ts} +4 -8
- package/dist/types/storage/turso.d.ts.map +1 -0
- package/dist/{storage/unstorage.d.mts → types/storage/unstorage.d.ts} +12 -11
- package/dist/types/storage/unstorage.d.ts.map +1 -0
- package/dist/types/subject.d.ts +115 -0
- package/dist/types/subject.d.ts.map +1 -0
- package/dist/types/themes/theme.d.ts +207 -0
- package/dist/types/themes/theme.d.ts.map +1 -0
- package/dist/types/toolkit/client.d.ts +235 -0
- package/dist/types/toolkit/client.d.ts.map +1 -0
- package/dist/types/toolkit/index.d.ts +45 -0
- package/dist/types/toolkit/index.d.ts.map +1 -0
- package/dist/types/toolkit/providers/facebook.d.ts +8 -0
- package/dist/types/toolkit/providers/facebook.d.ts.map +1 -0
- package/dist/types/toolkit/providers/github.d.ts +8 -0
- package/dist/types/toolkit/providers/github.d.ts.map +1 -0
- package/dist/types/toolkit/providers/google.d.ts +8 -0
- package/dist/types/toolkit/providers/google.d.ts.map +1 -0
- package/dist/types/toolkit/providers/strategy.d.ts +38 -0
- package/dist/types/toolkit/providers/strategy.d.ts.map +1 -0
- package/dist/{toolkit/storage.d.mts → types/toolkit/storage.d.ts} +37 -39
- package/dist/types/toolkit/storage.d.ts.map +1 -0
- package/dist/{toolkit/utils.d.mts → types/toolkit/utils.d.ts} +2 -4
- package/dist/types/toolkit/utils.d.ts.map +1 -0
- package/dist/types/types.d.ts +92 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/ui/base.d.ts +18 -0
- package/dist/types/ui/base.d.ts.map +1 -0
- package/dist/types/ui/code.d.ts +43 -0
- package/dist/types/ui/code.d.ts.map +1 -0
- package/dist/types/ui/form.d.ts +24 -0
- package/dist/types/ui/form.d.ts.map +1 -0
- package/dist/types/ui/icon.d.ts +60 -0
- package/dist/types/ui/icon.d.ts.map +1 -0
- package/dist/types/ui/magiclink.d.ts +41 -0
- package/dist/types/ui/magiclink.d.ts.map +1 -0
- package/dist/types/ui/password.d.ts +43 -0
- package/dist/types/ui/password.d.ts.map +1 -0
- package/dist/types/ui/select.d.ts +33 -0
- package/dist/types/ui/select.d.ts.map +1 -0
- package/dist/{util.d.mts → types/util.d.ts} +11 -13
- package/dist/types/util.d.ts.map +1 -0
- package/package.json +10 -16
- package/dist/adapters/node.d.mts +0 -18
- package/dist/adapters/node.mjs +0 -69
- package/dist/allow.mjs +0 -63
- package/dist/client.d.mts +0 -456
- package/dist/client.mjs +0 -283
- package/dist/core.d.mts +0 -110
- package/dist/core.mjs +0 -595
- package/dist/error.mjs +0 -237
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +0 -3
- package/dist/keys.mjs +0 -146
- package/dist/mutex.d.mts +0 -44
- package/dist/mutex.mjs +0 -110
- package/dist/pkce.mjs +0 -157
- package/dist/provider/apple.d.mts +0 -111
- package/dist/provider/apple.mjs +0 -164
- package/dist/provider/code.d.mts +0 -228
- package/dist/provider/code.mjs +0 -246
- package/dist/provider/discord.d.mts +0 -146
- package/dist/provider/discord.mjs +0 -156
- package/dist/provider/facebook.d.mts +0 -142
- package/dist/provider/facebook.mjs +0 -150
- package/dist/provider/github.d.mts +0 -140
- package/dist/provider/github.mjs +0 -169
- package/dist/provider/gitlab.d.mts +0 -106
- package/dist/provider/gitlab.mjs +0 -147
- package/dist/provider/google.d.mts +0 -112
- package/dist/provider/google.mjs +0 -109
- package/dist/provider/linkedin.d.mts +0 -132
- package/dist/provider/linkedin.mjs +0 -142
- package/dist/provider/magiclink.d.mts +0 -89
- package/dist/provider/magiclink.mjs +0 -143
- package/dist/provider/microsoft.d.mts +0 -178
- package/dist/provider/microsoft.mjs +0 -177
- package/dist/provider/oauth2.d.mts +0 -176
- package/dist/provider/oauth2.mjs +0 -222
- package/dist/provider/passkey.d.mts +0 -104
- package/dist/provider/passkey.mjs +0 -320
- package/dist/provider/password.d.mts +0 -412
- package/dist/provider/password.mjs +0 -363
- package/dist/provider/provider.d.mts +0 -227
- package/dist/provider/provider.mjs +0 -44
- package/dist/provider/reddit.d.mts +0 -107
- package/dist/provider/reddit.mjs +0 -127
- package/dist/provider/slack.d.mts +0 -114
- package/dist/provider/slack.mjs +0 -138
- package/dist/provider/spotify.d.mts +0 -113
- package/dist/provider/spotify.mjs +0 -135
- package/dist/provider/totp.d.mts +0 -112
- package/dist/provider/totp.mjs +0 -191
- package/dist/provider/twitch.d.mts +0 -108
- package/dist/provider/twitch.mjs +0 -131
- package/dist/provider/vercel.d.mts +0 -177
- package/dist/provider/vercel.mjs +0 -230
- package/dist/random.mjs +0 -86
- package/dist/revocation.d.mts +0 -55
- package/dist/revocation.mjs +0 -63
- package/dist/router/context.d.mts +0 -21
- package/dist/router/context.mjs +0 -193
- package/dist/router/cookies.d.mts +0 -8
- package/dist/router/cookies.mjs +0 -13
- package/dist/router/index.d.mts +0 -21
- package/dist/router/index.mjs +0 -107
- package/dist/router/matcher.d.mts +0 -15
- package/dist/router/matcher.mjs +0 -76
- package/dist/router/middleware/cors.d.mts +0 -15
- package/dist/router/middleware/cors.mjs +0 -114
- package/dist/router/safe-request.d.mts +0 -52
- package/dist/router/safe-request.mjs +0 -160
- package/dist/router/types.d.mts +0 -67
- package/dist/router/types.mjs +0 -1
- package/dist/router/variables.d.mts +0 -12
- package/dist/router/variables.mjs +0 -20
- package/dist/storage/memory.mjs +0 -125
- package/dist/storage/storage.d.mts +0 -179
- package/dist/storage/storage.mjs +0 -104
- package/dist/storage/turso.mjs +0 -117
- package/dist/storage/unstorage.mjs +0 -103
- package/dist/subject.d.mts +0 -62
- package/dist/subject.mjs +0 -36
- package/dist/themes/theme.d.mts +0 -209
- package/dist/themes/theme.mjs +0 -120
- package/dist/toolkit/client.d.mts +0 -169
- package/dist/toolkit/client.mjs +0 -209
- package/dist/toolkit/index.d.mts +0 -9
- package/dist/toolkit/index.mjs +0 -9
- package/dist/toolkit/providers/facebook.d.mts +0 -12
- package/dist/toolkit/providers/facebook.mjs +0 -16
- package/dist/toolkit/providers/github.d.mts +0 -12
- package/dist/toolkit/providers/github.mjs +0 -16
- package/dist/toolkit/providers/google.d.mts +0 -12
- package/dist/toolkit/providers/google.mjs +0 -20
- package/dist/toolkit/providers/strategy.d.mts +0 -40
- package/dist/toolkit/providers/strategy.mjs +0 -1
- package/dist/toolkit/storage.mjs +0 -157
- package/dist/toolkit/utils.mjs +0 -30
- package/dist/types.d.mts +0 -94
- package/dist/types.mjs +0 -1
- package/dist/ui/base.d.mts +0 -30
- package/dist/ui/base.mjs +0 -407
- package/dist/ui/code.d.mts +0 -43
- package/dist/ui/code.mjs +0 -173
- package/dist/ui/form.d.mts +0 -32
- package/dist/ui/form.mjs +0 -49
- package/dist/ui/icon.d.mts +0 -58
- package/dist/ui/icon.mjs +0 -247
- package/dist/ui/magiclink.d.mts +0 -41
- package/dist/ui/magiclink.mjs +0 -152
- package/dist/ui/passkey.d.mts +0 -27
- package/dist/ui/passkey.mjs +0 -323
- package/dist/ui/password.d.mts +0 -42
- package/dist/ui/password.mjs +0 -402
- package/dist/ui/select.d.mts +0 -34
- package/dist/ui/select.mjs +0 -98
- package/dist/ui/totp.d.mts +0 -34
- package/dist/ui/totp.mjs +0 -270
- package/dist/util.mjs +0 -128
package/dist/client.mjs
DELETED
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import { InvalidAccessTokenError, InvalidAuthorizationCodeError, InvalidRefreshTokenError, InvalidSubjectError } from "./error.mjs";
|
|
2
|
-
import { generatePKCE } from "./pkce.mjs";
|
|
3
|
-
import { createLocalJWKSet, errors, jwtVerify } from "jose";
|
|
4
|
-
|
|
5
|
-
//#region src/client.ts
|
|
6
|
-
/**
|
|
7
|
-
* Draft Auth client for OAuth 2.0 authentication.
|
|
8
|
-
*
|
|
9
|
-
* ## Quick Start
|
|
10
|
-
*
|
|
11
|
-
* First, create a client.
|
|
12
|
-
*
|
|
13
|
-
* ```ts title="client.ts"
|
|
14
|
-
* import { createClient } from "@draftlab/auth/client"
|
|
15
|
-
*
|
|
16
|
-
* const client = createClient({
|
|
17
|
-
* clientID: "my-client",
|
|
18
|
-
* issuer: "https://auth.myserver.com"
|
|
19
|
-
* })
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* Start the OAuth flow by calling `authorize`.
|
|
23
|
-
*
|
|
24
|
-
* ```ts
|
|
25
|
-
* const result = await client.authorize(
|
|
26
|
-
* "https://myapp.com/callback",
|
|
27
|
-
* "code"
|
|
28
|
-
* )
|
|
29
|
-
* if (result.success) {
|
|
30
|
-
* window.location.href = result.data.url
|
|
31
|
-
* }
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* When the user completes the flow, exchange the code for tokens.
|
|
35
|
-
*
|
|
36
|
-
* ```ts
|
|
37
|
-
* const result = await client.exchange(code, redirectUri)
|
|
38
|
-
* if (result.success) {
|
|
39
|
-
* const { access, refresh } = result.data
|
|
40
|
-
* // Store tokens securely
|
|
41
|
-
* }
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* Verify tokens to get user information.
|
|
45
|
-
*
|
|
46
|
-
* ```ts
|
|
47
|
-
* const result = await client.verify(subjects, accessToken)
|
|
48
|
-
* if (result.success) {
|
|
49
|
-
* // Access user properties: result.data.subject.properties
|
|
50
|
-
* }
|
|
51
|
-
* ```
|
|
52
|
-
*
|
|
53
|
-
* @packageDocumentation
|
|
54
|
-
*/
|
|
55
|
-
/**
|
|
56
|
-
* Create a Draft Auth client.
|
|
57
|
-
*
|
|
58
|
-
* @param input - Client configuration
|
|
59
|
-
* @returns Configured client instance
|
|
60
|
-
*
|
|
61
|
-
* @example Basic setup
|
|
62
|
-
* ```ts
|
|
63
|
-
* const client = createClient({
|
|
64
|
-
* clientID: "my-web-app",
|
|
65
|
-
* issuer: "https://auth.mycompany.com"
|
|
66
|
-
* })
|
|
67
|
-
* ```
|
|
68
|
-
*/
|
|
69
|
-
const createClient = (input) => {
|
|
70
|
-
const jwksCache = /* @__PURE__ */ new Map();
|
|
71
|
-
const issuerCache = /* @__PURE__ */ new Map();
|
|
72
|
-
const issuer = input.issuer;
|
|
73
|
-
if (!issuer) throw new Error("No issuer configured");
|
|
74
|
-
const f = input.fetch ?? fetch;
|
|
75
|
-
const getIssuer = async () => {
|
|
76
|
-
const cached = issuerCache.get(issuer);
|
|
77
|
-
if (cached) return cached;
|
|
78
|
-
const wellKnown = await f(`${issuer}/.well-known/oauth-authorization-server`).then((r) => r.json());
|
|
79
|
-
issuerCache.set(issuer, wellKnown);
|
|
80
|
-
return wellKnown;
|
|
81
|
-
};
|
|
82
|
-
const getJWKS = async () => {
|
|
83
|
-
const wk = await getIssuer();
|
|
84
|
-
const cached = jwksCache.get(issuer);
|
|
85
|
-
if (cached) return cached;
|
|
86
|
-
const result = createLocalJWKSet(await f(wk.jwks_uri).then((r) => r.json()));
|
|
87
|
-
jwksCache.set(issuer, result);
|
|
88
|
-
return result;
|
|
89
|
-
};
|
|
90
|
-
const client = {
|
|
91
|
-
async authorize(redirectURI, response, opts) {
|
|
92
|
-
try {
|
|
93
|
-
const wk = await getIssuer();
|
|
94
|
-
const authUrl = new URL(wk.authorization_endpoint);
|
|
95
|
-
const challenge = { state: crypto.randomUUID() };
|
|
96
|
-
authUrl.searchParams.set("client_id", input.clientID);
|
|
97
|
-
authUrl.searchParams.set("redirect_uri", redirectURI);
|
|
98
|
-
authUrl.searchParams.set("response_type", response);
|
|
99
|
-
authUrl.searchParams.set("state", challenge.state);
|
|
100
|
-
if (opts?.provider) authUrl.searchParams.set("provider", opts.provider);
|
|
101
|
-
if (opts?.pkce && response === "code") {
|
|
102
|
-
const pkce = await generatePKCE();
|
|
103
|
-
authUrl.searchParams.set("code_challenge_method", "S256");
|
|
104
|
-
authUrl.searchParams.set("code_challenge", pkce.challenge);
|
|
105
|
-
challenge.verifier = pkce.verifier;
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
success: true,
|
|
109
|
-
data: {
|
|
110
|
-
challenge,
|
|
111
|
-
url: authUrl.toString()
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
} catch (error) {
|
|
115
|
-
return {
|
|
116
|
-
success: false,
|
|
117
|
-
error
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
async exchange(code, redirectURI, verifier) {
|
|
122
|
-
try {
|
|
123
|
-
const response = await f((await getIssuer()).token_endpoint, {
|
|
124
|
-
method: "POST",
|
|
125
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
126
|
-
body: new URLSearchParams({
|
|
127
|
-
code,
|
|
128
|
-
redirect_uri: redirectURI,
|
|
129
|
-
grant_type: "authorization_code",
|
|
130
|
-
client_id: input.clientID,
|
|
131
|
-
...verifier ? { code_verifier: verifier } : {}
|
|
132
|
-
}).toString()
|
|
133
|
-
});
|
|
134
|
-
if (!response.ok) return {
|
|
135
|
-
success: false,
|
|
136
|
-
error: new InvalidAuthorizationCodeError()
|
|
137
|
-
};
|
|
138
|
-
const responseText = await response.text();
|
|
139
|
-
let json;
|
|
140
|
-
try {
|
|
141
|
-
json = JSON.parse(responseText);
|
|
142
|
-
} catch {
|
|
143
|
-
return {
|
|
144
|
-
success: false,
|
|
145
|
-
error: new InvalidAuthorizationCodeError()
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
const tokenResponse = json;
|
|
149
|
-
return {
|
|
150
|
-
success: true,
|
|
151
|
-
data: {
|
|
152
|
-
access: tokenResponse.access_token,
|
|
153
|
-
refresh: tokenResponse.refresh_token,
|
|
154
|
-
expiresIn: tokenResponse.expires_in
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
} catch {
|
|
158
|
-
return {
|
|
159
|
-
success: false,
|
|
160
|
-
error: new InvalidAuthorizationCodeError()
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
async refresh(refresh, opts) {
|
|
165
|
-
try {
|
|
166
|
-
if (opts?.access) try {
|
|
167
|
-
const jwks = await getJWKS();
|
|
168
|
-
await jwtVerify(opts.access, jwks, { issuer });
|
|
169
|
-
return {
|
|
170
|
-
success: true,
|
|
171
|
-
data: {}
|
|
172
|
-
};
|
|
173
|
-
} catch {}
|
|
174
|
-
const response = await f((await getIssuer()).token_endpoint, {
|
|
175
|
-
method: "POST",
|
|
176
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
177
|
-
body: new URLSearchParams({
|
|
178
|
-
refresh_token: refresh,
|
|
179
|
-
grant_type: "refresh_token"
|
|
180
|
-
}).toString()
|
|
181
|
-
});
|
|
182
|
-
if (!response.ok) return {
|
|
183
|
-
success: false,
|
|
184
|
-
error: new InvalidRefreshTokenError()
|
|
185
|
-
};
|
|
186
|
-
const tokenResponse = await response.json();
|
|
187
|
-
return {
|
|
188
|
-
success: true,
|
|
189
|
-
data: { tokens: {
|
|
190
|
-
access: tokenResponse.access_token,
|
|
191
|
-
refresh: tokenResponse.refresh_token,
|
|
192
|
-
expiresIn: tokenResponse.expires_in
|
|
193
|
-
} }
|
|
194
|
-
};
|
|
195
|
-
} catch {
|
|
196
|
-
return {
|
|
197
|
-
success: false,
|
|
198
|
-
error: new InvalidRefreshTokenError()
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
async verify(subjects, token, options) {
|
|
203
|
-
try {
|
|
204
|
-
const jwtResult = await jwtVerify(token, await getJWKS(), {
|
|
205
|
-
issuer: options?.issuer ?? issuer,
|
|
206
|
-
audience: options?.audience ?? input.clientID
|
|
207
|
-
});
|
|
208
|
-
const validated = await subjects[jwtResult.payload.type]?.["~standard"].validate(jwtResult.payload.properties);
|
|
209
|
-
if (!validated?.issues && jwtResult.payload.mode === "access") return {
|
|
210
|
-
success: true,
|
|
211
|
-
data: {
|
|
212
|
-
aud: jwtResult.payload.aud,
|
|
213
|
-
subject: {
|
|
214
|
-
type: jwtResult.payload.type,
|
|
215
|
-
properties: validated?.value
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
return {
|
|
220
|
-
success: false,
|
|
221
|
-
error: new InvalidSubjectError()
|
|
222
|
-
};
|
|
223
|
-
} catch (e) {
|
|
224
|
-
if (e instanceof errors.JWTExpired && options?.refresh) {
|
|
225
|
-
const refreshed = await client.refresh(options.refresh);
|
|
226
|
-
if (!refreshed.success) return refreshed;
|
|
227
|
-
if (!refreshed.data.tokens) return {
|
|
228
|
-
success: false,
|
|
229
|
-
error: new InvalidAccessTokenError()
|
|
230
|
-
};
|
|
231
|
-
const verified = await client.verify(subjects, refreshed.data.tokens.access, {
|
|
232
|
-
refresh: refreshed.data.tokens.refresh,
|
|
233
|
-
issuer: options?.issuer,
|
|
234
|
-
audience: options?.audience,
|
|
235
|
-
fetch: options?.fetch
|
|
236
|
-
});
|
|
237
|
-
if (!verified.success) return verified;
|
|
238
|
-
return {
|
|
239
|
-
success: true,
|
|
240
|
-
data: {
|
|
241
|
-
...verified.data,
|
|
242
|
-
tokens: refreshed.data.tokens
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
return {
|
|
247
|
-
success: false,
|
|
248
|
-
error: new InvalidAccessTokenError()
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
},
|
|
252
|
-
async revoke(token, opts) {
|
|
253
|
-
try {
|
|
254
|
-
const wk = await getIssuer();
|
|
255
|
-
const body = new URLSearchParams({
|
|
256
|
-
token,
|
|
257
|
-
...opts?.tokenTypeHint ? { token_type_hint: opts.tokenTypeHint } : {}
|
|
258
|
-
});
|
|
259
|
-
if ((await f(wk.token_endpoint.replace("/token", "/revoke"), {
|
|
260
|
-
method: "POST",
|
|
261
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
262
|
-
body: body.toString()
|
|
263
|
-
})).ok) return {
|
|
264
|
-
success: true,
|
|
265
|
-
data: void 0
|
|
266
|
-
};
|
|
267
|
-
return {
|
|
268
|
-
success: false,
|
|
269
|
-
error: /* @__PURE__ */ new Error("Failed to revoke token")
|
|
270
|
-
};
|
|
271
|
-
} catch (error) {
|
|
272
|
-
return {
|
|
273
|
-
success: false,
|
|
274
|
-
error
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
return client;
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
//#endregion
|
|
283
|
-
export { createClient };
|
package/dist/core.d.mts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { AllowCheckInput } from "./allow.mjs";
|
|
2
|
-
import { UnknownStateError } from "./error.mjs";
|
|
3
|
-
import { Prettify } from "./util.mjs";
|
|
4
|
-
import { SubjectPayload, SubjectSchema } from "./subject.mjs";
|
|
5
|
-
import { Router } from "./router/index.mjs";
|
|
6
|
-
import { StorageAdapter } from "./storage/storage.mjs";
|
|
7
|
-
import { Provider } from "./provider/provider.mjs";
|
|
8
|
-
import { Theme } from "./themes/theme.mjs";
|
|
9
|
-
import { AuthorizationState } from "./types.mjs";
|
|
10
|
-
|
|
11
|
-
//#region src/core.d.ts
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Sets the subject payload in the JWT token and returns the response.
|
|
15
|
-
*/
|
|
16
|
-
interface OnSuccessResponder<T extends {
|
|
17
|
-
type: string;
|
|
18
|
-
properties: unknown;
|
|
19
|
-
}> {
|
|
20
|
-
subject<Type extends T["type"]>(type: Type, properties: Extract<T, {
|
|
21
|
-
type: Type;
|
|
22
|
-
}>["properties"], opts?: {
|
|
23
|
-
ttl?: {
|
|
24
|
-
access?: number;
|
|
25
|
-
refresh?: number;
|
|
26
|
-
};
|
|
27
|
-
subject?: string;
|
|
28
|
-
}): Promise<Response>;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Main issuer input configuration interface.
|
|
32
|
-
*/
|
|
33
|
-
interface IssuerInput<Providers extends Record<string, Provider<unknown>>, Subjects extends SubjectSchema, Result = { [Key in keyof Providers]: Prettify<{
|
|
34
|
-
provider: Key;
|
|
35
|
-
} & (Providers[Key] extends Provider<infer T> ? T : Record<string, unknown>)> }[keyof Providers]> {
|
|
36
|
-
/** The storage adapter for persisting tokens and sessions */
|
|
37
|
-
storage: StorageAdapter;
|
|
38
|
-
/** Auth providers configuration */
|
|
39
|
-
providers: Providers;
|
|
40
|
-
/** Subject schemas for token validation */
|
|
41
|
-
subjects: Subjects;
|
|
42
|
-
/** Base path for embedded scenarios */
|
|
43
|
-
basePath?: string;
|
|
44
|
-
/** Success callback for completed authentication */
|
|
45
|
-
success(response: OnSuccessResponder<SubjectPayload<Subjects>>, input: Result, req: Request, clientID: string): Promise<Response>;
|
|
46
|
-
/** Theme configuration for UI */
|
|
47
|
-
theme?: Theme;
|
|
48
|
-
/** TTL configuration for tokens and sessions */
|
|
49
|
-
ttl?: {
|
|
50
|
-
access?: number;
|
|
51
|
-
refresh?: number;
|
|
52
|
-
reuse?: number;
|
|
53
|
-
retention?: number;
|
|
54
|
-
};
|
|
55
|
-
/** Provider selection UI function */
|
|
56
|
-
select?(providers: Record<string, string>, req: Request): Promise<Response>;
|
|
57
|
-
/** Optional start callback */
|
|
58
|
-
start?(req: Request): Promise<void>;
|
|
59
|
-
/** Error handling callback */
|
|
60
|
-
error?(error: UnknownStateError, req: Request): Promise<Response>;
|
|
61
|
-
/** Client authorization check function */
|
|
62
|
-
allow?(input: AllowCheckInput, req: Request): Promise<boolean>;
|
|
63
|
-
/**
|
|
64
|
-
* Refresh callback for updating user claims.
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```typescript
|
|
68
|
-
* refresh: async (payload, req) => {
|
|
69
|
-
* const user = await getUserBySubject(payload.subject)
|
|
70
|
-
* if (!user || !user.active) {
|
|
71
|
-
* return undefined // Revoke the token
|
|
72
|
-
* }
|
|
73
|
-
*
|
|
74
|
-
* return {
|
|
75
|
-
* type: payload.type,
|
|
76
|
-
* properties: {
|
|
77
|
-
* userID: user.id,
|
|
78
|
-
* role: user.role,
|
|
79
|
-
* permissions: user.permissions,
|
|
80
|
-
* lastLogin: new Date().toISOString()
|
|
81
|
-
* }
|
|
82
|
-
* }
|
|
83
|
-
* }
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
refresh?(payload: {
|
|
87
|
-
type: SubjectPayload<Subjects>["type"];
|
|
88
|
-
properties: SubjectPayload<Subjects>["properties"];
|
|
89
|
-
subject: string;
|
|
90
|
-
clientID: string;
|
|
91
|
-
scopes?: string[];
|
|
92
|
-
}, req: Request): Promise<{
|
|
93
|
-
type: SubjectPayload<Subjects>["type"];
|
|
94
|
-
properties: SubjectPayload<Subjects>["properties"];
|
|
95
|
-
subject?: string;
|
|
96
|
-
scopes?: string[];
|
|
97
|
-
} | undefined>;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Create an Draft Auth server, a Router app that handles OAuth 2.0 flows.
|
|
101
|
-
*/
|
|
102
|
-
declare const issuer: <Providers extends Record<string, Provider<unknown>>, Subjects extends SubjectSchema, Result = { [key in keyof Providers]: {
|
|
103
|
-
provider: key;
|
|
104
|
-
} & (Providers[key] extends Provider<infer T> ? T : Record<string, unknown>) }[keyof Providers]>(input: IssuerInput<Providers, Subjects, Result>) => Router<{
|
|
105
|
-
Variables: {
|
|
106
|
-
authorization: AuthorizationState;
|
|
107
|
-
};
|
|
108
|
-
}>;
|
|
109
|
-
//#endregion
|
|
110
|
-
export { OnSuccessResponder, issuer };
|