@growth-labs/auth 0.1.3 → 0.2.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/README.md +132 -34
- package/dist/client/login-page.d.ts +16 -1
- package/dist/client/login-page.d.ts.map +1 -1
- package/dist/client/login-page.js +20 -1
- package/dist/client/login-page.js.map +1 -1
- package/dist/middleware/auth.js +2 -2
- package/dist/middleware/auth.js.map +1 -1
- package/dist/routes/callback.d.ts.map +1 -1
- package/dist/routes/callback.js +27 -4
- package/dist/routes/callback.js.map +1 -1
- package/dist/routes/forgot-password.d.ts +12 -1
- package/dist/routes/forgot-password.d.ts.map +1 -1
- package/dist/routes/forgot-password.js +14 -54
- package/dist/routes/forgot-password.js.map +1 -1
- package/dist/routes/login.d.ts.map +1 -1
- package/dist/routes/login.js +21 -27
- package/dist/routes/login.js.map +1 -1
- package/dist/routes/reset-password.d.ts +10 -0
- package/dist/routes/reset-password.d.ts.map +1 -1
- package/dist/routes/reset-password.js +12 -44
- package/dist/routes/reset-password.js.map +1 -1
- package/dist/types.d.ts +18 -14
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cookies.d.ts +18 -0
- package/dist/utils/cookies.d.ts.map +1 -1
- package/dist/utils/cookies.js +27 -0
- package/dist/utils/cookies.js.map +1 -1
- package/dist/utils/index.d.ts +4 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/openauth.d.ts +50 -5
- package/dist/utils/openauth.d.ts.map +1 -1
- package/dist/utils/openauth.js +70 -18
- package/dist/utils/openauth.js.map +1 -1
- package/dist/utils/tokens.d.ts +5 -8
- package/dist/utils/tokens.d.ts.map +1 -1
- package/dist/utils/tokens.js +54 -24
- package/dist/utils/tokens.js.map +1 -1
- package/package.json +74 -58
package/dist/utils/tokens.js
CHANGED
|
@@ -1,27 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
|
2
2
|
const jwksCache = new Map();
|
|
3
|
-
|
|
3
|
+
function getJWKS(issuer) {
|
|
4
4
|
let jwks = jwksCache.get(issuer);
|
|
5
5
|
if (jwks)
|
|
6
6
|
return jwks;
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
throw new Error(`JWKS fetch failed: ${response.status}`);
|
|
10
|
-
const data = (await response.json());
|
|
11
|
-
jwks = createLocalJWKSet(data);
|
|
7
|
+
const jwksUrl = new URL('/.well-known/jwks.json', issuer);
|
|
8
|
+
jwks = createRemoteJWKSet(jwksUrl);
|
|
12
9
|
jwksCache.set(issuer, jwks);
|
|
13
10
|
return jwks;
|
|
14
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Extract subject claims from an OpenAuth-issued JWT payload.
|
|
14
|
+
*
|
|
15
|
+
* OpenAuth places the subject payload (defined by the issuer's `subjects`
|
|
16
|
+
* schema) under `properties` in the access token. The standalone
|
|
17
|
+
* identity-platform issuer's subject contains:
|
|
18
|
+
* - userId, email, name, image, isNewUser
|
|
19
|
+
*
|
|
20
|
+
* The JWT's top-level `sub` is `{type}:{sha1-prefix}` (an OpenAuth-internal
|
|
21
|
+
* subject hash, NOT the user ID). Always read the user ID from
|
|
22
|
+
* `properties.userId`.
|
|
23
|
+
*/
|
|
24
|
+
function extractClaims(payload) {
|
|
25
|
+
const propsCandidate = payload.properties;
|
|
26
|
+
const props = propsCandidate && typeof propsCandidate === 'object'
|
|
27
|
+
? propsCandidate
|
|
28
|
+
: {};
|
|
29
|
+
const userId = typeof props.userId === 'string' ? props.userId : null;
|
|
30
|
+
const email = typeof props.email === 'string' ? props.email : null;
|
|
31
|
+
if (!userId || !email) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
userId,
|
|
36
|
+
email,
|
|
37
|
+
name: typeof props.name === 'string' ? props.name : undefined,
|
|
38
|
+
image: typeof props.image === 'string' ? props.image : undefined,
|
|
39
|
+
isNewUser: typeof props.isNewUser === 'boolean' ? props.isNewUser : undefined,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
15
42
|
export async function verifyAccessToken(issuer, token) {
|
|
16
43
|
try {
|
|
17
|
-
const jwks =
|
|
44
|
+
const jwks = getJWKS(issuer);
|
|
18
45
|
const { payload } = await jwtVerify(token, jwks, { issuer });
|
|
19
|
-
return
|
|
20
|
-
sub: payload.sub,
|
|
21
|
-
email: payload.email,
|
|
22
|
-
name: payload.name,
|
|
23
|
-
image: payload.image,
|
|
24
|
-
};
|
|
46
|
+
return extractClaims(payload);
|
|
25
47
|
}
|
|
26
48
|
catch (err) {
|
|
27
49
|
console.error('verifyAccessToken error:', err);
|
|
@@ -36,7 +58,8 @@ export async function refreshTokens(issuer, refreshToken, clientId) {
|
|
|
36
58
|
});
|
|
37
59
|
if (clientId)
|
|
38
60
|
params.set('client_id', clientId);
|
|
39
|
-
const
|
|
61
|
+
const tokenUrl = new URL('/token', issuer).toString();
|
|
62
|
+
const response = await fetch(tokenUrl, {
|
|
40
63
|
method: 'POST',
|
|
41
64
|
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
42
65
|
body: params.toString(),
|
|
@@ -44,16 +67,15 @@ export async function refreshTokens(issuer, refreshToken, clientId) {
|
|
|
44
67
|
if (!response.ok)
|
|
45
68
|
return null;
|
|
46
69
|
const data = (await response.json());
|
|
47
|
-
|
|
70
|
+
if (!data.access_token || !data.refresh_token)
|
|
71
|
+
return null;
|
|
72
|
+
const claims = extractClaims(decodeJwtPayload(data.access_token));
|
|
73
|
+
if (!claims)
|
|
74
|
+
return null;
|
|
48
75
|
return {
|
|
49
76
|
accessToken: data.access_token,
|
|
50
77
|
refreshToken: data.refresh_token,
|
|
51
|
-
claims
|
|
52
|
-
sub: claims.sub,
|
|
53
|
-
email: claims.email,
|
|
54
|
-
name: claims.name,
|
|
55
|
-
image: claims.image,
|
|
56
|
-
},
|
|
78
|
+
claims,
|
|
57
79
|
};
|
|
58
80
|
}
|
|
59
81
|
catch {
|
|
@@ -64,9 +86,17 @@ export function decodeJwtPayload(jwt) {
|
|
|
64
86
|
const parts = jwt.split('.');
|
|
65
87
|
if (parts.length !== 3)
|
|
66
88
|
return {};
|
|
67
|
-
const
|
|
68
|
-
|
|
89
|
+
const padded = parts[1].replace(/-/g, '+').replace(/_/g, '/');
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(atob(padded));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
69
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Exposed for tests so cached JWKS sets can be reset between cases.
|
|
99
|
+
*/
|
|
70
100
|
export function _resetJwksCache() {
|
|
71
101
|
jwksCache.clear();
|
|
72
102
|
}
|
package/dist/utils/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,59 +1,75 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
2
|
+
"name": "@growth-labs/auth",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "OpenAuth client package for Astro + Cloudflare. Verifies JWTs, manages session cookies, gates protected paths, and injects login/logout/callback routes.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"astro",
|
|
7
|
+
"astro-integration",
|
|
8
|
+
"openauth",
|
|
9
|
+
"oauth",
|
|
10
|
+
"cloudflare-workers",
|
|
11
|
+
"auth"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/growth-labs/platform.git",
|
|
17
|
+
"directory": "packages/auth"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/growth-labs/platform/tree/main/packages/auth#readme",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public",
|
|
22
|
+
"registry": "https://registry.npmjs.org/"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./utils": {
|
|
31
|
+
"types": "./dist/utils/index.d.ts",
|
|
32
|
+
"import": "./dist/utils/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./middleware/*": {
|
|
35
|
+
"types": "./dist/middleware/*.d.ts",
|
|
36
|
+
"import": "./dist/middleware/*.js"
|
|
37
|
+
},
|
|
38
|
+
"./routes/*": {
|
|
39
|
+
"types": "./dist/routes/*.d.ts",
|
|
40
|
+
"import": "./dist/routes/*.js"
|
|
41
|
+
},
|
|
42
|
+
"./types": {
|
|
43
|
+
"types": "./dist/types.d.ts",
|
|
44
|
+
"import": "./dist/types.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"README.md"
|
|
50
|
+
],
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"astro": "^6.0.0",
|
|
53
|
+
"@growth-labs/analytics": "^0.1.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"@growth-labs/analytics": {
|
|
57
|
+
"optional": true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"zod": "^3.23.0",
|
|
62
|
+
"jose": "^6.0.0"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"astro": "^6.0.0",
|
|
66
|
+
"typescript": "^5.8.0",
|
|
67
|
+
"vitest": "^3.0.0",
|
|
68
|
+
"@growth-labs/analytics": "0.1.3"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsc",
|
|
72
|
+
"test": "vitest run",
|
|
73
|
+
"test:watch": "vitest"
|
|
74
|
+
}
|
|
75
|
+
}
|