@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 CHANGED
@@ -1,4 +1,14 @@
1
- # AdonisJS Jwt Auth
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<User>): JwtContent => ({
57
- userId: user.getId(),
58
- email: user.getOriginal().email,
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
- tokenExpiresIn?: number | string;
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>>;
@@ -5,6 +5,7 @@ export function jwtGuard(config) {
5
5
  const appKey = app.config.get('app.appKey').release();
6
6
  const options = {
7
7
  secret: appKey,
8
+ tokenName: config.tokenName,
8
9
  expiresIn: config.tokenExpiresIn,
9
10
  useCookies: config.useCookies,
10
11
  content: config.content,
@@ -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: string | number | undefined;
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 { symbols, errors } from '@adonisjs/auth';
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('token', token, {
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('token') ??
75
- (this.#ctx.request.request.headers.cookie.match(/token=(.*?)(;|$)/) || [])[1];
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
  /**
@@ -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]: RealUser;
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
- expiresIn?: number | string;
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.2.2",
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 . --ext=.ts",
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.3",
38
- "@adonisjs/auth": "^9.1.1",
39
- "@adonisjs/core": "^6.3.1",
40
- "@adonisjs/eslint-config": "^1.3.0",
41
- "@adonisjs/lucid": "^20.5.1",
42
- "@adonisjs/prettier-config": "^1.3.0",
43
- "@adonisjs/tsconfig": "^1.3.0",
44
- "@japa/assert": "^2.1.0",
45
- "@japa/runner": "^3.1.1",
46
- "@swc/core": "^1.4.6",
47
- "@types/node": "^20.11.25",
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": "^8.57.0",
51
+ "eslint": "^9.26.0",
52
52
  "luxon": "^3.4.4",
53
53
  "np": "^10.0.0",
54
- "prettier": "^3.2.5",
54
+ "prettier": "^3.5.3",
55
55
  "timekeeper": "^2.3.1",
56
56
  "ts-node": "^10.9.2",
57
- "typescript": "^5.4.2"
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.2.0"
65
+ "@adonisjs/core": "^6.15.0"
65
66
  },
66
67
  "author": "MaximeMRF",
67
68
  "license": "MIT",