@fraym/auth 0.3.1 → 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
@@ -38,7 +38,51 @@ Use a `.env` file or env variables to configure cte clients and the command:
38
38
  AUTH_SERVER_ADDRESS=127.0.0.1:9000
39
39
  ```
40
40
 
41
- ## Usage
41
+ ## JWT functions
42
+
43
+ ### Create a new JWT for usage with fraym
44
+
45
+ ```typescript
46
+ const jwt = await generateJwt(appSecret, tenantId, scopes, data, expirationTime);
47
+ ```
48
+
49
+ Parameters:
50
+
51
+ - `appSecret`: the secret used to sign the jwt
52
+ - `tenantId`: the id of the tenant to use
53
+ - `scopes`: (optional) list of scopes available in this token
54
+ - `data`: (optional) data added to the `data` field of the token
55
+ - `expirationTime`: (optional) string is resolved to a time span and added to the current timestamp to calculate the expiration time
56
+
57
+ ### Add data to an existing JWT
58
+
59
+ Note: this will validate the existing token first.
60
+
61
+ ```typescript
62
+ const jwt = await addDataToJwt(appSecret, token, data);
63
+ ```
64
+
65
+ Parameters:
66
+
67
+ - `appSecret`: the secret used to sign the jwt
68
+ - `token`: the existing jwt
69
+ - `data`: (optional) data added to the `data` field of the token, existing fields in the data object will be overwritten
70
+
71
+ ### Validate the token and get associated data
72
+
73
+ Get scopes:
74
+
75
+ ```typescript
76
+ const { scopes, userId, exp } = await getTokenData(appSecret, token, requireUserId);
77
+ ```
78
+
79
+ Parameters:
80
+
81
+ - `appSecret`: the secret used to sign the jwt
82
+ - `token`: the existing jwt
83
+ - `requireUserId`: (optional, default: `true`) If set to true the function will throw an error if it cannot determine the id of the user that owns the jwt
84
+
85
+ ## Client Usage
42
86
 
43
87
  ### Create the client
44
88
 
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./management/client";
2
2
  export { ClientConfig } from "./config/config";
3
+ export * from "./util/token";
package/dist/index.js CHANGED
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./management/client"), exports);
18
+ __exportStar(require("./util/token"), exports);
@@ -0,0 +1,8 @@
1
+ export declare const generateJwt: (appSecret: string, tenantId: string, scopes?: string[], data?: Record<string, any>, expirationTime?: string) => Promise<string>;
2
+ export declare const addDataToJwt: (appSecret: string, token: string, data: Record<string, any>) => Promise<string>;
3
+ export interface TokenData {
4
+ userId: string;
5
+ scopes: string[];
6
+ exp: number;
7
+ }
8
+ export declare const getTokenData: (appSecret: string, token: string, requireUserId?: boolean) => Promise<TokenData>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTokenData = exports.addDataToJwt = exports.generateJwt = void 0;
4
+ const jose_1 = require("jose");
5
+ const alg = "HS256";
6
+ const generateJwt = async (appSecret, tenantId, scopes = [], data = {}, expirationTime = "5m") => {
7
+ const secret = new TextEncoder().encode(appSecret);
8
+ return await new jose_1.SignJWT({
9
+ type: "access_token",
10
+ tenantId,
11
+ scopes,
12
+ data,
13
+ })
14
+ .setProtectedHeader({
15
+ alg,
16
+ typ: "JWT",
17
+ })
18
+ .setIssuedAt()
19
+ .setNotBefore("0s")
20
+ .setIssuer("auth")
21
+ .setAudience(["fraym"])
22
+ .setExpirationTime(expirationTime)
23
+ .sign(secret);
24
+ };
25
+ exports.generateJwt = generateJwt;
26
+ const addDataToJwt = async (appSecret, token, data) => {
27
+ var _a;
28
+ const secret = new TextEncoder().encode(appSecret);
29
+ const { payload, protectedHeader } = await (0, jose_1.jwtVerify)(token, secret);
30
+ if (!payload.exp) {
31
+ throw Error("expiration time is missing in JWT");
32
+ }
33
+ const newData = (_a = payload.data) !== null && _a !== void 0 ? _a : {};
34
+ for (let key in data) {
35
+ newData[key] = data[key];
36
+ }
37
+ return new jose_1.SignJWT(Object.assign(Object.assign({}, payload), { data: newData }))
38
+ .setProtectedHeader(protectedHeader)
39
+ .sign(secret);
40
+ };
41
+ exports.addDataToJwt = addDataToJwt;
42
+ const getTokenData = async (appSecret, token, requireUserId = true) => {
43
+ var _a, _b;
44
+ const secret = new TextEncoder().encode(appSecret);
45
+ const { payload } = await (0, jose_1.jwtVerify)(token, secret);
46
+ if (!payload.exp) {
47
+ throw Error("expiration time is missing in JWT");
48
+ }
49
+ if (requireUserId && !payload.jti) {
50
+ throw Error("expiration time is missing in JWT");
51
+ }
52
+ return {
53
+ scopes: (_a = payload.scopes) !== null && _a !== void 0 ? _a : [],
54
+ userId: (_b = payload.jti) !== null && _b !== void 0 ? _b : "",
55
+ exp: payload.exp,
56
+ };
57
+ };
58
+ exports.getTokenData = getTokenData;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fraym/auth",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "license": "UNLICENSED",
5
5
  "homepage": "https://github.com/fraym/auth-nodejs",
6
6
  "repository": {
@@ -33,6 +33,7 @@
33
33
  "@grpc/grpc-js": "^1.8.7",
34
34
  "dotenv": "^16.0.3",
35
35
  "graphql": "^16.6.0",
36
+ "jose": "^4.13.1",
36
37
  "yargs": "^17.6.2"
37
38
  },
38
39
  "devDependencies": {