@maximemrf/adonisjs-jwt 0.7.0-alpha.1 → 0.7.0-alpha.2
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 +10 -8
- package/build/src/define_config.d.ts +2 -0
- package/build/src/define_config.js +3 -0
- package/build/src/jwks.d.ts +7 -0
- package/build/src/jwks.js +14 -0
- package/build/src/jwt.js +16 -2
- package/build/src/types.d.ts +4 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -199,16 +199,18 @@ router.post('login', async ({ request, auth }) => {
|
|
|
199
199
|
})
|
|
200
200
|
|
|
201
201
|
// if the jwt guard is the default guard
|
|
202
|
-
router
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
router
|
|
203
|
+
.get('/', async ({ auth }) => {
|
|
204
|
+
return auth.getUserOrFail()
|
|
205
|
+
})
|
|
206
|
+
.use(middleware.auth())
|
|
206
207
|
|
|
207
208
|
// if the jwt guard is not the default guard
|
|
208
|
-
router
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
router
|
|
210
|
+
.get('/', async ({ auth }) => {
|
|
211
|
+
return auth.use('jwt').getUserOrFail()
|
|
212
|
+
})
|
|
213
|
+
.use(middleware.auth({ guards: ['jwt'] }))
|
|
212
214
|
|
|
213
215
|
// if you use the refresh token
|
|
214
216
|
router.post('jwt/refresh', async ({ auth }) => {
|
|
@@ -4,6 +4,7 @@ import { JwtGuardUser, JwtUserProviderContract } from './types.js';
|
|
|
4
4
|
import { JwtGuard } from './jwt.js';
|
|
5
5
|
import type { StringValue } from 'ms';
|
|
6
6
|
import { AccessTokensUserProviderContract } from '@adonisjs/auth/types/access_tokens';
|
|
7
|
+
import { Options } from 'jwks-rsa';
|
|
7
8
|
export declare function jwtGuard<UserProvider extends JwtUserProviderContract<unknown>>(config: {
|
|
8
9
|
provider: UserProvider;
|
|
9
10
|
refreshTokenUserProvider?: AccessTokensUserProviderContract<unknown>;
|
|
@@ -15,4 +16,5 @@ export declare function jwtGuard<UserProvider extends JwtUserProviderContract<un
|
|
|
15
16
|
refreshTokenAbilities?: string[];
|
|
16
17
|
secret?: string;
|
|
17
18
|
content: <T>(user: JwtGuardUser<T>) => Record<string | number, any>;
|
|
19
|
+
jwks?: Options;
|
|
18
20
|
}): GuardConfigProvider<(ctx: HttpContext) => JwtGuard<UserProvider>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JwtGuard } from './jwt.js';
|
|
2
|
+
import { JwksManager } from './jwks.js';
|
|
2
3
|
export function jwtGuard(config) {
|
|
3
4
|
return {
|
|
4
5
|
async resolver(_, app) {
|
|
@@ -13,6 +14,8 @@ export function jwtGuard(config) {
|
|
|
13
14
|
useCookiesForRefreshToken: config.useCookiesForRefreshToken,
|
|
14
15
|
refreshTokenAbilities: config.refreshTokenAbilities,
|
|
15
16
|
content: config.content,
|
|
17
|
+
jwks: config.jwks,
|
|
18
|
+
jwksClient: config.jwks ? new JwksManager(config.jwks).getClient() : undefined,
|
|
16
19
|
};
|
|
17
20
|
return (ctx) => new JwtGuard(ctx, config.provider, options);
|
|
18
21
|
},
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { JwksClient } from 'jwks-rsa';
|
|
2
|
+
export class JwksManager {
|
|
3
|
+
client;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.client = new JwksClient(options);
|
|
6
|
+
}
|
|
7
|
+
getClient() {
|
|
8
|
+
return this.client;
|
|
9
|
+
}
|
|
10
|
+
async getSigningKey(kid) {
|
|
11
|
+
const key = await this.client.getSigningKey(kid);
|
|
12
|
+
return key.getPublicKey();
|
|
13
|
+
}
|
|
14
|
+
}
|
package/build/src/jwt.js
CHANGED
|
@@ -8,6 +8,7 @@ export class JwtGuard {
|
|
|
8
8
|
#options;
|
|
9
9
|
#tokenName;
|
|
10
10
|
#refreshTokenName = 'refreshToken';
|
|
11
|
+
#jwksManager;
|
|
11
12
|
constructor(ctx, userProvider, option) {
|
|
12
13
|
this.#ctx = ctx;
|
|
13
14
|
this.#userProvider = userProvider;
|
|
@@ -16,6 +17,7 @@ export class JwtGuard {
|
|
|
16
17
|
if (!this.#options.content)
|
|
17
18
|
this.#options.content = (user) => ({ userId: user.getId() });
|
|
18
19
|
this.#tokenName = this.#options.tokenName ?? 'token';
|
|
20
|
+
this.#jwksManager = this.#options.jwksManager;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* A unique name for the guard driver
|
|
@@ -126,14 +128,26 @@ export class JwtGuard {
|
|
|
126
128
|
*/
|
|
127
129
|
let payload;
|
|
128
130
|
try {
|
|
129
|
-
|
|
131
|
+
if (this.#jwksManager) {
|
|
132
|
+
const decoded = jwt.decode(token, { complete: true });
|
|
133
|
+
if (!decoded || !decoded.header || !decoded.header.kid) {
|
|
134
|
+
throw new errors.E_UNAUTHORIZED_ACCESS('Unauthorized access', {
|
|
135
|
+
guardDriverName: this.driverName,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const key = await this.#jwksManager.getSigningKey(decoded.header.kid);
|
|
139
|
+
payload = jwt.verify(token, key);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
payload = jwt.verify(token, this.#options.secret);
|
|
143
|
+
}
|
|
130
144
|
}
|
|
131
145
|
catch (error) {
|
|
132
146
|
throw new errors.E_UNAUTHORIZED_ACCESS('Unauthorized access', {
|
|
133
147
|
guardDriverName: this.driverName,
|
|
134
148
|
});
|
|
135
149
|
}
|
|
136
|
-
if (typeof payload !== 'object' || !('userId' in payload)) {
|
|
150
|
+
if (!payload || typeof payload !== 'object' || !('userId' in payload)) {
|
|
137
151
|
throw new errors.E_UNAUTHORIZED_ACCESS('Unauthorized access', {
|
|
138
152
|
guardDriverName: this.driverName,
|
|
139
153
|
});
|
package/build/src/types.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { symbols } from '@adonisjs/auth';
|
|
2
2
|
import type { StringValue } from 'ms';
|
|
3
3
|
import { AccessTokensUserProviderContract } from '@adonisjs/auth/types/access_tokens';
|
|
4
|
+
import { Options } from 'jwks-rsa';
|
|
5
|
+
import { JwksManager } from './jwks.js';
|
|
4
6
|
/**
|
|
5
7
|
* The bridge between the User provider and the
|
|
6
8
|
* Guard
|
|
@@ -40,6 +42,8 @@ export type BaseJwtContent = {
|
|
|
40
42
|
};
|
|
41
43
|
export type JwtGuardOptions<RealUser extends any = unknown> = {
|
|
42
44
|
secret: string;
|
|
45
|
+
jwks?: Options;
|
|
46
|
+
jwksManager?: JwksManager;
|
|
43
47
|
refreshTokenUserProvider?: AccessTokensUserProviderContract<RealUser>;
|
|
44
48
|
tokenName?: string;
|
|
45
49
|
expiresIn?: number | StringValue;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maximemrf/adonisjs-jwt",
|
|
3
3
|
"description": "Adonisjs v6 package for authentication with jwt token",
|
|
4
|
-
"version": "0.7.0-alpha.
|
|
4
|
+
"version": "0.7.0-alpha.2",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.6.0"
|
|
7
7
|
},
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@types/jsonwebtoken": "^9.0.10",
|
|
63
63
|
"jsonwebtoken": "^9.0.3",
|
|
64
|
+
"jwks-rsa": "^3.2.2",
|
|
64
65
|
"ms": "^2.1.3"
|
|
65
66
|
},
|
|
66
67
|
"peerDependencies": {
|
|
@@ -97,4 +98,4 @@
|
|
|
97
98
|
"tests/**"
|
|
98
99
|
]
|
|
99
100
|
}
|
|
100
|
-
}
|
|
101
|
+
}
|