@elysiajs/jwt 0.6.3 → 0.6.4
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 +47 -30
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,104 +1,121 @@
|
|
|
1
1
|
# @elysiajs/static
|
|
2
|
+
|
|
2
3
|
Plugin for [Elysia](https://github.com/elysiajs/elysia) for using JWT Authentication.
|
|
3
4
|
|
|
4
5
|
## Installation
|
|
6
|
+
|
|
5
7
|
```bash
|
|
6
8
|
bun add @elysiajs/jwt
|
|
7
9
|
```
|
|
8
10
|
|
|
9
11
|
## Example
|
|
12
|
+
|
|
10
13
|
```typescript
|
|
11
|
-
import { Elysia, t } from 'elysia'
|
|
12
|
-
import { jwt } from '@elysiajs/jwt'
|
|
13
|
-
import { cookie } from '@elysiajs/cookie'
|
|
14
|
+
import { Elysia, t } from 'elysia';
|
|
15
|
+
import { jwt } from '@elysiajs/jwt';
|
|
16
|
+
import { cookie } from '@elysiajs/cookie';
|
|
14
17
|
|
|
15
18
|
const app = new Elysia()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
})
|
|
22
|
-
)
|
|
23
|
-
.use(cookie())
|
|
24
|
-
.get('/sign/:name', async ({ jwt, cookie, setCookie, params }) => {
|
|
25
|
-
setCookie('auth', await jwt.sign(params), {
|
|
26
|
-
httpOnly: true
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
return `Sign in as ${params.name}`
|
|
30
|
-
})
|
|
31
|
-
.get('/profile', async ({ jwt, set, cookie: { auth } }) => {
|
|
32
|
-
const profile = await jwt.verify(auth)
|
|
33
|
-
|
|
34
|
-
if (!profile) {
|
|
35
|
-
set.status = 401
|
|
36
|
-
return 'Unauthorized'
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return `Hello ${profile.name}`
|
|
19
|
+
.use(
|
|
20
|
+
jwt({
|
|
21
|
+
name: 'jwt',
|
|
22
|
+
// This should be Environment Variable
|
|
23
|
+
secret: 'MY_SECRETS',
|
|
40
24
|
})
|
|
41
|
-
|
|
25
|
+
)
|
|
26
|
+
.use(cookie())
|
|
27
|
+
.get('/sign/:name', async ({ jwt, cookie, setCookie, params }) => {
|
|
28
|
+
setCookie('auth', await jwt.sign(params), {
|
|
29
|
+
httpOnly: true,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return `Sign in as ${params.name}`;
|
|
33
|
+
})
|
|
34
|
+
.get('/profile', async ({ jwt, set, cookie: { auth } }) => {
|
|
35
|
+
const profile = await jwt.verify(auth);
|
|
36
|
+
|
|
37
|
+
if (!profile) {
|
|
38
|
+
set.status = 401;
|
|
39
|
+
return 'Unauthorized';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return `Hello ${profile.name}`;
|
|
43
|
+
})
|
|
44
|
+
.listen(8080);
|
|
42
45
|
```
|
|
43
46
|
|
|
44
47
|
## Config
|
|
45
|
-
|
|
48
|
+
|
|
49
|
+
This package extends [jose](https://github.com/panva/jose), most config is inherited from Jose.
|
|
46
50
|
|
|
47
51
|
Below are configurable properties for using JWT plugin
|
|
48
52
|
|
|
49
53
|
### name
|
|
54
|
+
|
|
50
55
|
Name to decorate method as:
|
|
51
56
|
|
|
52
57
|
For example, `jwt` will decorate Context with `Context.jwt`
|
|
53
58
|
|
|
54
59
|
### secret
|
|
60
|
+
|
|
55
61
|
JWT secret key
|
|
56
62
|
|
|
57
63
|
### schema
|
|
64
|
+
|
|
58
65
|
Type strict validation for JWT payload
|
|
59
66
|
|
|
60
67
|
## Jose's config
|
|
68
|
+
|
|
61
69
|
Below is the config inherits from [jose](https://github.com/panva/jose)
|
|
62
70
|
|
|
63
71
|
### alg
|
|
72
|
+
|
|
64
73
|
@default 'HS256'
|
|
65
74
|
|
|
66
75
|
Algorithm to sign JWT with
|
|
67
76
|
|
|
68
77
|
### crit
|
|
78
|
+
|
|
69
79
|
Critical Header Parameter.
|
|
70
80
|
|
|
71
81
|
### iss
|
|
82
|
+
|
|
72
83
|
JWT Issuer
|
|
73
84
|
|
|
74
85
|
@see [RFC7519#section-4.1.1](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1)
|
|
75
86
|
|
|
76
87
|
### sub
|
|
88
|
+
|
|
77
89
|
JWT Subject
|
|
78
90
|
|
|
79
91
|
@see [RFC7519#section-4.1.2](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2)
|
|
80
92
|
|
|
81
93
|
### aud
|
|
82
|
-
|
|
94
|
+
|
|
95
|
+
JWT Audience
|
|
83
96
|
|
|
84
97
|
@see [RFC7519#section-4.1.3](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3)
|
|
85
98
|
|
|
86
99
|
### jti
|
|
100
|
+
|
|
87
101
|
JWT ID
|
|
88
102
|
|
|
89
103
|
@see [RFC7519#section-4.1.7](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7)
|
|
90
104
|
|
|
91
105
|
### nbf
|
|
106
|
+
|
|
92
107
|
JWT Not Before
|
|
93
108
|
|
|
94
109
|
@see [RFC7519#section-4.1.5](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5)
|
|
95
110
|
|
|
96
111
|
### exp
|
|
112
|
+
|
|
97
113
|
JWT Expiration Time
|
|
98
114
|
|
|
99
115
|
@see [RFC7519#section-4.1.4](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4)
|
|
100
116
|
|
|
101
117
|
### iat
|
|
118
|
+
|
|
102
119
|
JWT Issued At
|
|
103
120
|
|
|
104
121
|
@see [RFC7519#section-4.1.6](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6)
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
|
-
import { type JWTPayload, type JWSHeaderParameters } from 'jose';
|
|
2
|
+
import { type JWTPayload, type JWSHeaderParameters, type KeyLike } from 'jose';
|
|
3
3
|
import type { Static, TSchema } from '@sinclair/typebox';
|
|
4
4
|
type UnwrapSchema<Schema extends TSchema | undefined, Fallback = unknown> = Schema extends TSchema ? Static<NonNullable<Schema>> : Fallback;
|
|
5
5
|
export interface JWTPayloadSpec {
|
|
@@ -13,7 +13,7 @@ export interface JWTPayloadSpec {
|
|
|
13
13
|
}
|
|
14
14
|
export interface JWTOption<Name extends string | undefined = 'jwt', Schema extends TSchema | undefined = undefined> extends JWSHeaderParameters, Omit<JWTPayload, 'nbf' | 'exp'> {
|
|
15
15
|
name?: Name;
|
|
16
|
-
secret: string;
|
|
16
|
+
secret: string | Uint8Array | KeyLike;
|
|
17
17
|
schema?: Schema;
|
|
18
18
|
nbf?: string | number;
|
|
19
19
|
exp?: string | number;
|
package/dist/cjs/index.js
CHANGED
|
@@ -7,9 +7,9 @@ const typebox_1 = require("@sinclair/typebox");
|
|
|
7
7
|
const jwt = ({ name = 'jwt', secret, alg = 'HS256', crit, schema, nbf, exp, ...payload }) => {
|
|
8
8
|
if (!secret)
|
|
9
9
|
throw new Error("Secret can't be empty");
|
|
10
|
-
const key = new TextEncoder().encode(secret);
|
|
10
|
+
const key = typeof secret === 'string' ? new TextEncoder().encode(secret) : secret;
|
|
11
11
|
const validator = schema
|
|
12
|
-
? (0, elysia_1.getSchemaValidator)(typebox_1.Type.
|
|
12
|
+
? (0, elysia_1.getSchemaValidator)(typebox_1.Type.Intersect([
|
|
13
13
|
schema,
|
|
14
14
|
typebox_1.Type.Object({
|
|
15
15
|
iss: typebox_1.Type.Optional(typebox_1.Type.String()),
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
|
-
import { type JWTPayload, type JWSHeaderParameters } from 'jose';
|
|
2
|
+
import { type JWTPayload, type JWSHeaderParameters, type KeyLike } from 'jose';
|
|
3
3
|
import type { Static, TSchema } from '@sinclair/typebox';
|
|
4
4
|
type UnwrapSchema<Schema extends TSchema | undefined, Fallback = unknown> = Schema extends TSchema ? Static<NonNullable<Schema>> : Fallback;
|
|
5
5
|
export interface JWTPayloadSpec {
|
|
@@ -13,7 +13,7 @@ export interface JWTPayloadSpec {
|
|
|
13
13
|
}
|
|
14
14
|
export interface JWTOption<Name extends string | undefined = 'jwt', Schema extends TSchema | undefined = undefined> extends JWSHeaderParameters, Omit<JWTPayload, 'nbf' | 'exp'> {
|
|
15
15
|
name?: Name;
|
|
16
|
-
secret: string;
|
|
16
|
+
secret: string | Uint8Array | KeyLike;
|
|
17
17
|
schema?: Schema;
|
|
18
18
|
nbf?: string | number;
|
|
19
19
|
exp?: string | number;
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ValidationError, getSchemaValidator
|
|
1
|
+
import { Elysia, ValidationError, getSchemaValidator } from 'elysia';
|
|
2
2
|
import { SignJWT, jwtVerify } from 'jose';
|
|
3
3
|
import { Type as t } from '@sinclair/typebox';
|
|
4
4
|
export const jwt = ({ name = 'jwt', secret, alg = 'HS256', crit, schema, nbf, exp, ...payload }) => {
|
|
5
5
|
if (!secret)
|
|
6
6
|
throw new Error("Secret can't be empty");
|
|
7
|
-
const key = new TextEncoder().encode(secret);
|
|
7
|
+
const key = typeof secret === 'string' ? new TextEncoder().encode(secret) : secret;
|
|
8
8
|
const validator = schema
|
|
9
|
-
? getSchemaValidator(t.
|
|
9
|
+
? getSchemaValidator(t.Intersect([
|
|
10
10
|
schema,
|
|
11
11
|
t.Object({
|
|
12
12
|
iss: t.Optional(t.String()),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elysiajs/jwt",
|
|
3
3
|
"description": "Plugin for Elysia for using JWT Authentication",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.4",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "saltyAom",
|
|
7
7
|
"url": "https://github.com/SaltyAom",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"scripts": {
|
|
33
33
|
"dev": "bun run --hot example/index.ts",
|
|
34
|
-
"test": "bun
|
|
34
|
+
"test": "bun test && npm run test:node",
|
|
35
35
|
"test:node": "npm install --prefix ./test/node/cjs/ && npm install --prefix ./test/node/esm/ && node ./test/node/cjs/index.js && node ./test/node/esm/index.js",
|
|
36
36
|
"build": "rimraf dist && tsc --project tsconfig.esm.json && tsc --project tsconfig.cjs.json",
|
|
37
37
|
"release": "npm run build && npm run test && npm publish --access public"
|
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
"@elysiajs/cookie": "^0.3.0",
|
|
44
44
|
"@sinclair/typebox": "^0.30.4",
|
|
45
45
|
"@types/node": "^20.1.4",
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
|
47
|
+
"@typescript-eslint/parser": "^6.6.0",
|
|
46
48
|
"bun-types": "^0.5.8",
|
|
47
49
|
"elysia": "0.6.6",
|
|
48
50
|
"eslint": "^8.40.0",
|