@maximemrf/adonisjs-jwt 0.2.2 → 0.4.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 +25 -5
- package/build/src/define_config.d.ts +3 -1
- package/build/src/define_config.js +1 -0
- package/build/src/jwt.d.ts +10 -4
- package/build/src/jwt.js +8 -4
- package/build/src/types.d.ts +4 -2
- package/package.json +19 -18
package/README.md
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://maximemax.sirv.com/npm_package_maxime_jwt.png" alt="@maximemrf/adonisjs-jwt">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@maximemrf/adonisjs-jwt"><img src="https://img.shields.io/npm/dm/@maximemrf/adonisjs-jwt.svg?style=flat-square" alt="Download"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/@maximemrf/adonisjs-jwt"><img src="https://img.shields.io/npm/v/@maximemrf/adonisjs-jwt.svg?style=flat-square" alt="Version"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/@maximemrf/adonisjs-jwt"><img src="https://img.shields.io/npm/last-update/@maximemrf/adonisjs-jwt.svg?style=flat-square" alt="NPM Last Update"></a>
|
|
9
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/npm/l/@maximemrf/adonisjs-jwt.svg?style=flat-square" alt="License"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
2
12
|
> AdonisJS package to authenticate users using JWT tokens.
|
|
3
13
|
|
|
4
14
|
## Prerequisites
|
|
@@ -45,6 +55,8 @@ const authConfig = defineConfig({
|
|
|
45
55
|
}),
|
|
46
56
|
// add the jwt guard
|
|
47
57
|
jwt: jwtGuard({
|
|
58
|
+
// tokenName is the name of the token passed as cookie, it can be optional, by default it is 'token'
|
|
59
|
+
tokenName: 'custom-name',
|
|
48
60
|
// tokenExpiresIn can be a string or a number, it can be optional
|
|
49
61
|
tokenExpiresIn: '1h',
|
|
50
62
|
// if you want to use cookies for the authentication instead of the bearer token (optional)
|
|
@@ -53,15 +65,23 @@ const authConfig = defineConfig({
|
|
|
53
65
|
model: () => import('#models/user'),
|
|
54
66
|
}),
|
|
55
67
|
// content is a function that takes the user and returns the content of the token, it can be optional, by default it returns only the user id
|
|
56
|
-
content: (user: JwtGuardUser<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
content: <T>(user: JwtGuardUser<T>): JwtContent => {
|
|
69
|
+
return {
|
|
70
|
+
userId: user.getId(),
|
|
71
|
+
email: (user.getOriginal() as User).email,
|
|
72
|
+
}
|
|
73
|
+
},
|
|
60
74
|
}),
|
|
61
75
|
},
|
|
62
76
|
})
|
|
63
77
|
```
|
|
64
78
|
|
|
79
|
+
`tokenName` is the name of the token passed as a cookie, it can be optional, by default it is `token`.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
tokenName: 'custom-name'
|
|
83
|
+
```
|
|
84
|
+
|
|
65
85
|
`tokenExpiresIn` is the time before the token expires it can be a string or a number and it can be optional.
|
|
66
86
|
|
|
67
87
|
```typescript
|
|
@@ -2,9 +2,11 @@ import { GuardConfigProvider } from '@adonisjs/auth/types';
|
|
|
2
2
|
import type { HttpContext } from '@adonisjs/core/http';
|
|
3
3
|
import { JwtGuardUser, JwtUserProviderContract } from './types.js';
|
|
4
4
|
import { JwtGuard } from './jwt.js';
|
|
5
|
+
import type { StringValue } from 'ms';
|
|
5
6
|
export declare function jwtGuard<UserProvider extends JwtUserProviderContract<unknown>>(config: {
|
|
6
7
|
provider: UserProvider;
|
|
7
|
-
|
|
8
|
+
tokenName?: string;
|
|
9
|
+
tokenExpiresIn?: number | StringValue;
|
|
8
10
|
useCookies?: boolean;
|
|
9
11
|
content: <T>(user: JwtGuardUser<T>) => Record<string | number, any>;
|
|
10
12
|
}): GuardConfigProvider<(ctx: HttpContext) => JwtGuard<UserProvider>>;
|
package/build/src/jwt.d.ts
CHANGED
|
@@ -27,21 +27,25 @@ export declare class JwtGuard<UserProvider extends JwtUserProviderContract<unkno
|
|
|
27
27
|
/**
|
|
28
28
|
* Reference to the currently authenticated user
|
|
29
29
|
*/
|
|
30
|
-
user?: UserProvider[typeof symbols.PROVIDER_REAL_USER]
|
|
30
|
+
user?: UserProvider[typeof symbols.PROVIDER_REAL_USER] & {
|
|
31
|
+
currentToken: string;
|
|
32
|
+
};
|
|
31
33
|
/**
|
|
32
34
|
* Generate a JWT token for a given user.
|
|
33
35
|
*/
|
|
34
36
|
generate(user: UserProvider[typeof symbols.PROVIDER_REAL_USER]): Promise<import("@adonisjs/core/http").Response | {
|
|
35
37
|
type: string;
|
|
36
38
|
token: string;
|
|
37
|
-
expiresIn:
|
|
39
|
+
expiresIn: number | import("ms").StringValue | undefined;
|
|
38
40
|
}>;
|
|
39
41
|
/**
|
|
40
42
|
* Authenticate the current HTTP request and return
|
|
41
43
|
* the user instance if there is a valid JWT token
|
|
42
44
|
* or throw an exception
|
|
43
45
|
*/
|
|
44
|
-
authenticate(): Promise<UserProvider[typeof symbols.PROVIDER_REAL_USER]
|
|
46
|
+
authenticate(): Promise<UserProvider[typeof symbols.PROVIDER_REAL_USER] & {
|
|
47
|
+
currentToken: string;
|
|
48
|
+
}>;
|
|
45
49
|
/**
|
|
46
50
|
* Same as authenticate, but does not throw an exception
|
|
47
51
|
*/
|
|
@@ -49,7 +53,9 @@ export declare class JwtGuard<UserProvider extends JwtUserProviderContract<unkno
|
|
|
49
53
|
/**
|
|
50
54
|
* Returns the authenticated user or throws an error
|
|
51
55
|
*/
|
|
52
|
-
getUserOrFail(): UserProvider[typeof symbols.PROVIDER_REAL_USER]
|
|
56
|
+
getUserOrFail(): UserProvider[typeof symbols.PROVIDER_REAL_USER] & {
|
|
57
|
+
currentToken: string;
|
|
58
|
+
};
|
|
53
59
|
/**
|
|
54
60
|
* This method is called by Japa during testing when "loginAs"
|
|
55
61
|
* method is used to login the user.
|
package/build/src/jwt.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { errors } from '@adonisjs/auth';
|
|
2
2
|
import jwt from 'jsonwebtoken';
|
|
3
3
|
export class JwtGuard {
|
|
4
4
|
#ctx;
|
|
5
5
|
#userProvider;
|
|
6
6
|
#options;
|
|
7
|
+
#tokenName;
|
|
7
8
|
constructor(ctx, userProvider, option) {
|
|
8
9
|
this.#ctx = ctx;
|
|
9
10
|
this.#userProvider = userProvider;
|
|
10
11
|
this.#options = option;
|
|
11
12
|
if (!this.#options.content)
|
|
12
13
|
this.#options.content = (user) => ({ userId: user.getId() });
|
|
14
|
+
this.#tokenName = this.#options.tokenName ?? 'token';
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* A unique name for the guard driver
|
|
@@ -40,7 +42,7 @@ export class JwtGuard {
|
|
|
40
42
|
}
|
|
41
43
|
: {});
|
|
42
44
|
if (this.#options.useCookies) {
|
|
43
|
-
return this.#ctx.response.cookie(
|
|
45
|
+
return this.#ctx.response.cookie(`${this.#tokenName}`, token, {
|
|
44
46
|
httpOnly: true,
|
|
45
47
|
});
|
|
46
48
|
}
|
|
@@ -70,9 +72,10 @@ export class JwtGuard {
|
|
|
70
72
|
* If cookies are enabled, then read the token from the cookies
|
|
71
73
|
*/
|
|
72
74
|
if (cookieHeader) {
|
|
75
|
+
const regex = new RegExp(`${this.#tokenName}=([^;]*)`);
|
|
73
76
|
token =
|
|
74
|
-
this.#ctx.request.cookie(
|
|
75
|
-
(this.#ctx.request.request.headers.cookie.match(
|
|
77
|
+
this.#ctx.request.cookie(`${this.#tokenName}`) ??
|
|
78
|
+
(this.#ctx.request.request.headers.cookie.match(regex) || [])[1];
|
|
76
79
|
}
|
|
77
80
|
/**
|
|
78
81
|
* If token is missing on cookies, then try to read it from the header authorization
|
|
@@ -126,6 +129,7 @@ export class JwtGuard {
|
|
|
126
129
|
}
|
|
127
130
|
this.isAuthenticated = true;
|
|
128
131
|
this.user = providerUser.getOriginal();
|
|
132
|
+
this.user.currentToken = token;
|
|
129
133
|
return this.getUserOrFail();
|
|
130
134
|
}
|
|
131
135
|
/**
|
package/build/src/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { symbols } from '@adonisjs/auth';
|
|
2
|
+
import type { StringValue } from 'ms';
|
|
2
3
|
/**
|
|
3
4
|
* The bridge between the User provider and the
|
|
4
5
|
* Guard
|
|
@@ -22,7 +23,7 @@ export interface JwtUserProviderContract<RealUser> {
|
|
|
22
23
|
* A property the guard implementation can use to infer
|
|
23
24
|
* the data type of the actual user (aka RealUser)
|
|
24
25
|
*/
|
|
25
|
-
[symbols.PROVIDER_REAL_USER]
|
|
26
|
+
[symbols.PROVIDER_REAL_USER]?: RealUser;
|
|
26
27
|
/**
|
|
27
28
|
* Create a user object that acts as an adapter between
|
|
28
29
|
* the guard and real user value.
|
|
@@ -38,7 +39,8 @@ export type BaseJwtContent = {
|
|
|
38
39
|
};
|
|
39
40
|
export type JwtGuardOptions<RealUser extends any = unknown> = {
|
|
40
41
|
secret: string;
|
|
41
|
-
|
|
42
|
+
tokenName?: string;
|
|
43
|
+
expiresIn?: number | StringValue;
|
|
42
44
|
useCookies?: boolean;
|
|
43
45
|
content?: (user: JwtGuardUser<RealUser>) => Record<string, any>;
|
|
44
46
|
};
|
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.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.6.0"
|
|
7
7
|
},
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"clean": "del-cli build",
|
|
22
22
|
"copy:templates": "copyfiles \"stubs/**/*.stub\" build",
|
|
23
23
|
"typecheck": "tsc --noEmit",
|
|
24
|
-
"lint": "eslint .
|
|
24
|
+
"lint": "eslint .",
|
|
25
25
|
"format": "prettier --write .",
|
|
26
26
|
"quick:test": "node --import=./tsnode.esm.js --enable-source-maps bin/test.ts",
|
|
27
27
|
"pretest": "npm run lint",
|
|
@@ -34,34 +34,35 @@
|
|
|
34
34
|
"prepublishOnly": "npm run build"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@adonisjs/assembler": "^7.2
|
|
38
|
-
"@adonisjs/auth": "^9.
|
|
39
|
-
"@adonisjs/core": "^6.
|
|
40
|
-
"@adonisjs/eslint-config": "^
|
|
41
|
-
"@adonisjs/lucid": "^
|
|
42
|
-
"@adonisjs/prettier-config": "^1.
|
|
43
|
-
"@adonisjs/tsconfig": "^1.
|
|
44
|
-
"@japa/assert": "^
|
|
45
|
-
"@japa/runner": "^
|
|
46
|
-
"@swc/core": "
|
|
47
|
-
"@types/node": "^
|
|
37
|
+
"@adonisjs/assembler": "^7.8.2",
|
|
38
|
+
"@adonisjs/auth": "^9.4.0",
|
|
39
|
+
"@adonisjs/core": "^6.17.2",
|
|
40
|
+
"@adonisjs/eslint-config": "^2.0.0",
|
|
41
|
+
"@adonisjs/lucid": "^21.0.0",
|
|
42
|
+
"@adonisjs/prettier-config": "^1.4.4",
|
|
43
|
+
"@adonisjs/tsconfig": "^1.4.0",
|
|
44
|
+
"@japa/assert": "^4.0.1",
|
|
45
|
+
"@japa/runner": "^4.2.0",
|
|
46
|
+
"@swc/core": "1.11.24",
|
|
47
|
+
"@types/node": "^22.15.18",
|
|
48
48
|
"c8": "^9.1.0",
|
|
49
49
|
"copyfiles": "^2.4.1",
|
|
50
50
|
"del-cli": "^5.1.0",
|
|
51
|
-
"eslint": "^
|
|
51
|
+
"eslint": "^9.26.0",
|
|
52
52
|
"luxon": "^3.4.4",
|
|
53
53
|
"np": "^10.0.0",
|
|
54
|
-
"prettier": "^3.
|
|
54
|
+
"prettier": "^3.5.3",
|
|
55
55
|
"timekeeper": "^2.3.1",
|
|
56
56
|
"ts-node": "^10.9.2",
|
|
57
|
-
"typescript": "
|
|
57
|
+
"typescript": "~5.8"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@types/jsonwebtoken": "^9.0.6",
|
|
61
|
-
"jsonwebtoken": "^9.0.2"
|
|
61
|
+
"jsonwebtoken": "^9.0.2",
|
|
62
|
+
"ms": "^2.1.3"
|
|
62
63
|
},
|
|
63
64
|
"peerDependencies": {
|
|
64
|
-
"@adonisjs/core": "^6.
|
|
65
|
+
"@adonisjs/core": "^6.15.0"
|
|
65
66
|
},
|
|
66
67
|
"author": "MaximeMRF",
|
|
67
68
|
"license": "MIT",
|