@maximemrf/adonisjs-jwt 0.0.12 → 0.0.14
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 +67 -97
- package/build/src/jwt.js +15 -4
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,115 +1,85 @@
|
|
|
1
|
-
# AdonisJS
|
|
1
|
+
# AdonisJS Jwt Auth
|
|
2
|
+
> AdonisJS package to authenticate users using JWT tokens.
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
## Prerequisites
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
You have to install the auth package from AdonisJS with the session guard because the jwt package use some components from the session guard.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Clone the repo on your computer, or use `giget` to download this repo without the Git history.
|
|
10
|
-
```sh
|
|
11
|
-
npx giget@latest gh:adonisjs/pkg-starter-kit
|
|
12
|
-
```
|
|
13
|
-
- Install dependencies.
|
|
14
|
-
- Update the `package.json` file and define the `name`, `description`, `keywords`, and `author` properties.
|
|
15
|
-
- The repo is configured with an MIT license. Feel free to change that if you are not publishing under the MIT license.
|
|
16
|
-
|
|
17
|
-
## Folder structure
|
|
18
|
-
|
|
19
|
-
The starter kit mimics the folder structure of the official packages. Feel free to rename files and folders as per your requirements.
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
├── providers
|
|
23
|
-
├── src
|
|
24
|
-
├── bin
|
|
25
|
-
├── stubs
|
|
26
|
-
├── configure.ts
|
|
27
|
-
├── index.ts
|
|
28
|
-
├── LICENSE.md
|
|
29
|
-
├── package.json
|
|
30
|
-
├── README.md
|
|
31
|
-
├── tsconfig.json
|
|
32
|
-
├── tsnode.esm.js
|
|
8
|
+
```bash
|
|
9
|
+
node ace add @adonisjs/auth --guard=session
|
|
33
10
|
```
|
|
34
11
|
|
|
35
|
-
|
|
36
|
-
- The `index.ts` file is the main entry point of the package.
|
|
37
|
-
- The `tsnode.esm.js` file runs TypeScript code using TS-Node + SWC. Please read the code comment in this file to learn more.
|
|
38
|
-
- The `bin` directory contains the entry point file to run Japa tests.
|
|
39
|
-
- Learn more about [the `providers` directory](./providers/README.md).
|
|
40
|
-
- Learn more about [the `src` directory](./src/README.md).
|
|
41
|
-
- Learn more about [the `stubs` directory](./stubs/README.md).
|
|
42
|
-
|
|
43
|
-
### File system naming convention
|
|
44
|
-
|
|
45
|
-
We use `snake_case` naming conventions for the file system. The rule is enforced using ESLint. However, turn off the rule and use your preferred naming conventions.
|
|
46
|
-
|
|
47
|
-
## Peer dependencies
|
|
48
|
-
|
|
49
|
-
The starter kit has a peer dependency on `@adonisjs/core@6`. Since you are creating a package for AdonisJS, you must make it against a specific version of the framework core.
|
|
50
|
-
|
|
51
|
-
If your package needs Lucid to be functional, you may install `@adonisjs/lucid` as a development dependency and add it to the list of `peerDependencies`.
|
|
52
|
-
|
|
53
|
-
As a rule of thumb, packages installed in the user application should be part of the `peerDependencies` of your package and not the main dependency.
|
|
54
|
-
|
|
55
|
-
For example, if you install `@adonisjs/core` as a main dependency, then essentially, you are importing a separate copy of `@adonisjs/core` and not sharing the one from the user application. Here is a great article explaining [peer dependencies](https://blog.bitsrc.io/understanding-peer-dependencies-in-javascript-dbdb4ab5a7be).
|
|
56
|
-
|
|
57
|
-
## Published files
|
|
58
|
-
|
|
59
|
-
Instead of publishing your repo's source code to npm, you must cherry-pick files and folders to publish only the required files.
|
|
12
|
+
## Setup
|
|
60
13
|
|
|
61
|
-
|
|
14
|
+
Install the package:
|
|
62
15
|
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
"files": ["build/src", "build/providers", "build/stubs", "build/index.d.ts", "build/index.js"]
|
|
66
|
-
}
|
|
16
|
+
```bash
|
|
17
|
+
npm i @maximemrf/adonisjs-jwt
|
|
67
18
|
```
|
|
68
19
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
Go to `config/auth.ts` and add the following configuration:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { defineConfig } from '@adonisjs/auth'
|
|
26
|
+
import { InferAuthEvents, Authenticators } from '@adonisjs/auth/types'
|
|
27
|
+
import { sessionGuard, sessionUserProvider } from '@adonisjs/auth/session'
|
|
28
|
+
import { jwtGuard } from '@maximemrf/adonisjs-jwt/jwt_config'
|
|
29
|
+
|
|
30
|
+
const authConfig = defineConfig({
|
|
31
|
+
// define the default authenticator to jwt
|
|
32
|
+
default: 'jwt',
|
|
33
|
+
guards: {
|
|
34
|
+
web: sessionGuard({
|
|
35
|
+
useRememberMeTokens: false,
|
|
36
|
+
provider: sessionUserProvider({
|
|
37
|
+
model: () => import('#models/user'),
|
|
38
|
+
}),
|
|
39
|
+
}),
|
|
40
|
+
// add the jwt guard
|
|
41
|
+
jwt: jwtGuard({
|
|
42
|
+
// tokenExpiresIn can be a string or a number, it can be optional
|
|
43
|
+
tokenExpiresIn: '1h',
|
|
44
|
+
provider: sessionUserProvider({
|
|
45
|
+
model: () => import('#models/user'),
|
|
46
|
+
}),
|
|
47
|
+
}),
|
|
48
|
+
},
|
|
49
|
+
})
|
|
82
50
|
```
|
|
83
51
|
|
|
84
|
-
|
|
85
|
-
- The `./types` exports all the types defined inside the `./build/src/types.js` file (the compiled output).
|
|
86
|
-
|
|
87
|
-
Feel free to change the exports as per your requirements.
|
|
88
|
-
|
|
89
|
-
## Testing
|
|
52
|
+
`tokenExpiresIn` is the time before the token expires it can be a string or a number, it can be optional.
|
|
90
53
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
## TypeScript workflow
|
|
99
|
-
|
|
100
|
-
- The starter kit uses [tsc](https://www.typescriptlang.org/docs/handbook/compiler-options.html) for compiling the TypeScript to JavaScript when publishing the package.
|
|
101
|
-
- [TS-Node](https://typestrong.org/ts-node/) and [SWC](https://swc.rs/) are used to run tests without compiling the source code.
|
|
102
|
-
- The `tsconfig.json` file is extended from [`@adonisjs/tsconfig`](https://github.com/adonisjs/tooling-config/tree/main/packages/typescript-config) and uses the `NodeNext` module system. Meaning the packages are written using ES modules.
|
|
103
|
-
- You can perform type checking without compiling the source code using the `npm run type check` script.
|
|
54
|
+
```typescript
|
|
55
|
+
// string
|
|
56
|
+
tokenExpiresIn: '1h'
|
|
57
|
+
// number
|
|
58
|
+
tokenExpiresIn: 60 * 60
|
|
59
|
+
```
|
|
104
60
|
|
|
105
|
-
|
|
61
|
+
## Usage
|
|
106
62
|
|
|
107
|
-
|
|
63
|
+
To make a protected route, you have to use the `auth` middleware with the `jwt` guard.
|
|
108
64
|
|
|
109
|
-
|
|
65
|
+
```typescript
|
|
66
|
+
router.post('login', async ({ request, auth }) => {
|
|
67
|
+
const { email, password } = request.all()
|
|
68
|
+
const user = await User.verifyCredentials(email, password)
|
|
110
69
|
|
|
111
|
-
|
|
70
|
+
// to generate a token
|
|
71
|
+
return await auth.use('jwt').generate(user)
|
|
72
|
+
})
|
|
112
73
|
|
|
113
|
-
|
|
74
|
+
// if the jwt guard is the default guard
|
|
75
|
+
router.get('/', async ({ auth }) => {
|
|
76
|
+
return auth.getUserOrFail()
|
|
77
|
+
})
|
|
78
|
+
.use(middleware.auth())
|
|
114
79
|
|
|
115
|
-
|
|
80
|
+
// if the jwt guard is not the default guard
|
|
81
|
+
router.get('/', async ({ auth }) => {
|
|
82
|
+
return auth.use('jwt').getUserOrFail()
|
|
83
|
+
})
|
|
84
|
+
.use(middleware.auth({ guards: ['jwt'] }))
|
|
85
|
+
```
|
package/build/src/jwt.js
CHANGED
|
@@ -32,9 +32,11 @@ export class JwtGuard {
|
|
|
32
32
|
*/
|
|
33
33
|
async generate(user) {
|
|
34
34
|
const providerUser = await this.#userProvider.createUserForGuard(user);
|
|
35
|
-
const token = jwt.sign({ userId: providerUser.getId() }, this.#options.secret,
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
const token = jwt.sign({ userId: providerUser.getId() }, this.#options.secret, this.#options.expiresIn
|
|
36
|
+
? {
|
|
37
|
+
expiresIn: this.#options.expiresIn,
|
|
38
|
+
}
|
|
39
|
+
: {});
|
|
38
40
|
return {
|
|
39
41
|
type: 'bearer',
|
|
40
42
|
token: token,
|
|
@@ -76,7 +78,15 @@ export class JwtGuard {
|
|
|
76
78
|
/**
|
|
77
79
|
* Verify token
|
|
78
80
|
*/
|
|
79
|
-
|
|
81
|
+
let payload;
|
|
82
|
+
try {
|
|
83
|
+
payload = jwt.verify(token, this.#options.secret);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
throw new errors.E_UNAUTHORIZED_ACCESS('Unauthorized access', {
|
|
87
|
+
guardDriverName: this.driverName,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
80
90
|
if (typeof payload !== 'object' || !('userId' in payload)) {
|
|
81
91
|
throw new errors.E_UNAUTHORIZED_ACCESS('Unauthorized access', {
|
|
82
92
|
guardDriverName: this.driverName,
|
|
@@ -91,6 +101,7 @@ export class JwtGuard {
|
|
|
91
101
|
guardDriverName: this.driverName,
|
|
92
102
|
});
|
|
93
103
|
}
|
|
104
|
+
this.isAuthenticated = true;
|
|
94
105
|
this.user = providerUser.getOriginal();
|
|
95
106
|
return this.getUserOrFail();
|
|
96
107
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maximemrf/adonisjs-jwt",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.14",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.6.0"
|
|
7
7
|
},
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@adonisjs/auth": "^9.1.1",
|
|
42
42
|
"@adonisjs/core": "^6.3.1",
|
|
43
43
|
"@adonisjs/eslint-config": "^1.3.0",
|
|
44
|
-
"@adonisjs/lucid": "^20.
|
|
44
|
+
"@adonisjs/lucid": "^20.5.1",
|
|
45
45
|
"@adonisjs/prettier-config": "^1.3.0",
|
|
46
46
|
"@adonisjs/tsconfig": "^1.3.0",
|
|
47
47
|
"@japa/assert": "^2.1.0",
|
|
@@ -52,8 +52,10 @@
|
|
|
52
52
|
"copyfiles": "^2.4.1",
|
|
53
53
|
"del-cli": "^5.1.0",
|
|
54
54
|
"eslint": "^8.57.0",
|
|
55
|
+
"luxon": "^3.4.4",
|
|
55
56
|
"np": "^10.0.0",
|
|
56
57
|
"prettier": "^3.2.5",
|
|
58
|
+
"timekeeper": "^2.3.1",
|
|
57
59
|
"ts-node": "^10.9.2",
|
|
58
60
|
"typescript": "^5.4.2"
|
|
59
61
|
},
|