adminforth 1.1.66 → 1.1.67

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/auth.ts CHANGED
@@ -3,6 +3,7 @@ import jwt from 'jsonwebtoken';
3
3
 
4
4
  import crypto from 'crypto';
5
5
  import AdminForth from './index.js';
6
+ import { th } from '@faker-js/faker';
6
7
 
7
8
  // Function to generate a password hash using PBKDF2
8
9
  function calcPasswordHash(password, salt, iterations = 100000, keyLength = 64, digest = 'sha512') {
@@ -26,7 +27,18 @@ class AdminForthAuth {
26
27
  this.adminforth = adminforth;
27
28
  }
28
29
 
29
- issueJWT(payload) {
30
+ removeAuthCookie(response) {
31
+ response.setHeader('Set-Cookie', `adminforth_jwt=; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=Thu, 01 Jan 1970 00:00:00 GMT`);
32
+ }
33
+
34
+ setAuthCookie({ response, username, pk}: {
35
+ response: any, username: string, pk: string | null
36
+ }) {
37
+ const token = this.issueJWT({ username, pk, }, 'auth');
38
+ response.setHeader('Set-Cookie', `adminforth_jwt=${token}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict`);
39
+ }
40
+
41
+ issueJWT(payload: Object, type: string) {
30
42
  // read ADMINFORH_SECRET from environment if not drop error
31
43
  const secret = process.env.ADMINFORTH_SECRET;
32
44
  if (!secret) {
@@ -35,10 +47,10 @@ class AdminForthAuth {
35
47
 
36
48
  // issue JWT token
37
49
  const expiresIn = process.env.ADMINFORTH_AUTH_EXPIRESIN || '24h';
38
- return jwt.sign(payload, secret, { expiresIn });
50
+ return jwt.sign({...payload, t: type}, secret, { expiresIn });
39
51
  }
40
52
 
41
- async verify(jwtToken) {
53
+ async verify(jwtToken: string, mustHaveType: string): Promise<Object> {
42
54
  // read ADMINFORH_SECRET from environment if not drop error
43
55
  const secret = process.env.ADMINFORTH_SECRET;
44
56
  if (!secret) {
@@ -58,7 +70,10 @@ class AdminForthAuth {
58
70
  }
59
71
  return null;
60
72
  }
61
- const { pk } = decoded;
73
+ const { pk, t } = decoded;
74
+ if (t !== mustHaveType) {
75
+ throw new Error(`Invalid token type during verification: ${t}, must be ${mustHaveType}`);
76
+ }
62
77
  if (pk === null) {
63
78
  decoded.isRoot = true;
64
79
  } else {
package/dist/auth.js CHANGED
@@ -27,7 +27,14 @@ class AdminForthAuth {
27
27
  constructor(adminforth) {
28
28
  this.adminforth = adminforth;
29
29
  }
30
- issueJWT(payload) {
30
+ removeAuthCookie(response) {
31
+ response.setHeader('Set-Cookie', `adminforth_jwt=; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=Thu, 01 Jan 1970 00:00:00 GMT`);
32
+ }
33
+ setAuthCookie({ response, username, pk }) {
34
+ const token = this.issueJWT({ username, pk, }, 'auth');
35
+ response.setHeader('Set-Cookie', `adminforth_jwt=${token}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict`);
36
+ }
37
+ issueJWT(payload, type) {
31
38
  // read ADMINFORH_SECRET from environment if not drop error
32
39
  const secret = process.env.ADMINFORTH_SECRET;
33
40
  if (!secret) {
@@ -35,9 +42,9 @@ class AdminForthAuth {
35
42
  }
36
43
  // issue JWT token
37
44
  const expiresIn = process.env.ADMINFORTH_AUTH_EXPIRESIN || '24h';
38
- return jwt.sign(payload, secret, { expiresIn });
45
+ return jwt.sign(Object.assign(Object.assign({}, payload), { t: type }), secret, { expiresIn });
39
46
  }
40
- verify(jwtToken) {
47
+ verify(jwtToken, mustHaveType) {
41
48
  return __awaiter(this, void 0, void 0, function* () {
42
49
  // read ADMINFORH_SECRET from environment if not drop error
43
50
  const secret = process.env.ADMINFORTH_SECRET;
@@ -61,7 +68,10 @@ class AdminForthAuth {
61
68
  }
62
69
  return null;
63
70
  }
64
- const { pk } = decoded;
71
+ const { pk, t } = decoded;
72
+ if (t !== mustHaveType) {
73
+ throw new Error(`Invalid token type during verification: ${t}, must be ${mustHaveType}`);
74
+ }
65
75
  if (pk === null) {
66
76
  decoded.isRoot = true;
67
77
  }
package/dist/index.js CHANGED
@@ -541,7 +541,7 @@ class AdminForth {
541
541
  const { username, password } = body;
542
542
  let token;
543
543
  if (username === this.config.rootUser.username && password === this.config.rootUser.password) {
544
- token = this.auth.issueJWT({ username, pk: null });
544
+ this.auth.setAuthCookie({ response, username, pk: null });
545
545
  }
546
546
  else {
547
547
  // get resource from db
@@ -575,15 +575,12 @@ class AdminForth {
575
575
  console.log('User record', userRecord, passwordHash); // why does it has no hash?
576
576
  const valid = yield AdminForthAuth.verifyPassword(password, passwordHash);
577
577
  if (valid) {
578
- token = this.auth.issueJWT({
579
- username, pk: userRecord[userResource.columns.find((col) => col.primaryKey).name]
580
- });
578
+ this.auth.setAuthCookie({ response, username, pk: userRecord[userResource.columns.find((col) => col.primaryKey).name] });
581
579
  }
582
580
  else {
583
581
  return { error: INVALID_MESSAGE };
584
582
  }
585
583
  }
586
- response.setHeader('Set-Cookie', `adminforth_jwt=${token}; Path=${this.config.baseUrl || '/'}; HttpOnly; SameSite=Strict`);
587
584
  return { ok: true };
588
585
  }),
589
586
  });
@@ -599,7 +596,7 @@ class AdminForth {
599
596
  method: 'POST',
600
597
  path: '/logout',
601
598
  handler: (_e) => __awaiter(this, [_e], void 0, function* ({ response }) {
602
- response.setHeader('Set-Cookie', `adminforth_jwt=; Path=${this.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=Thu, 01 Jan 1970 00:00:00 GMT`);
599
+ this.auth.removeAuthCookie({ response });
603
600
  return { ok: true };
604
601
  }),
605
602
  });
@@ -14,8 +14,8 @@ const props = defineProps(['column', 'record', 'meta', 'resource', 'adminUser'])
14
14
  :mode="'split'"
15
15
  :theme="'light'"
16
16
  :language="'JSON'"
17
- :prev="props.record[props.meta.resourceColumns.resourceDataColumnName].oldRecord"
18
- :current="props.record[props.meta.resourceColumns.resourceDataColumnName].newRecord"
17
+ :prev="JSON.stringify(JSON.parse(props.record[props.meta.resourceColumns.resourceDataColumnName]).oldRecord, null, 2)"
18
+ :current="JSON.stringify(JSON.parse(props.record[props.meta.resourceColumns.resourceDataColumnName]).newRecord, null, 2)"
19
19
  />
20
20
  </template>
21
21
 
@@ -21,7 +21,6 @@ class AuditLogPlugin extends AdminForthPlugin {
21
21
  'oldRecord': oldRecord || {},
22
22
  'newRecord': newRecord
23
23
  };
24
- // console.log('newData', newData)
25
24
  const record = {
26
25
  [this.options.resourceColumns.resourceIdColumnName]: resource.resourceId,
27
26
  [this.options.resourceColumns.resourceActionColumnName]: action,
@@ -149,7 +149,7 @@ class ExpressServer {
149
149
  res.status(401).send('Unauthorized by AdminForth');
150
150
  return;
151
151
  }
152
- const adminforthUser = yield this.adminforth.auth.verify(jwt);
152
+ const adminforthUser = yield this.adminforth.auth.verify(jwt, 'auth');
153
153
  if (!adminforthUser) {
154
154
  res.status(401).send('Unauthorized by AdminForth');
155
155
  }
package/index.ts CHANGED
@@ -626,7 +626,7 @@ class AdminForth implements AdminForthClass {
626
626
  const { username, password } = body;
627
627
  let token;
628
628
  if (username === this.config.rootUser.username && password === this.config.rootUser.password) {
629
- token = this.auth.issueJWT({ username, pk: null });
629
+ this.auth.setAuthCookie({ response, username, pk: null });
630
630
  } else {
631
631
  // get resource from db
632
632
  if (!this.config.auth) {
@@ -664,15 +664,11 @@ class AdminForth implements AdminForthClass {
664
664
  console.log('User record', userRecord, passwordHash) // why does it has no hash?
665
665
  const valid = await AdminForthAuth.verifyPassword(password, passwordHash);
666
666
  if (valid) {
667
- token = this.auth.issueJWT({
668
- username, pk: userRecord[userResource.columns.find((col) => col.primaryKey).name]
669
- });
667
+ this.auth.setAuthCookie({ response, username, pk: userRecord[userResource.columns.find((col) => col.primaryKey).name] });
670
668
  } else {
671
669
  return { error: INVALID_MESSAGE };
672
670
  }
673
671
  }
674
-
675
- response.setHeader('Set-Cookie', `adminforth_jwt=${token}; Path=${this.config.baseUrl || '/'}; HttpOnly; SameSite=Strict`);
676
672
  return { ok: true };
677
673
  },
678
674
  });
@@ -690,7 +686,7 @@ class AdminForth implements AdminForthClass {
690
686
  method: 'POST',
691
687
  path: '/logout',
692
688
  handler: async ({ response }) => {
693
- response.setHeader('Set-Cookie', `adminforth_jwt=; Path=${this.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=Thu, 01 Jan 1970 00:00:00 GMT`);
689
+ this.auth.removeAuthCookie({ response });
694
690
  return { ok: true };
695
691
  },
696
692
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.1.66",
3
+ "version": "1.1.67",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -14,8 +14,8 @@ const props = defineProps(['column', 'record', 'meta', 'resource', 'adminUser'])
14
14
  :mode="'split'"
15
15
  :theme="'light'"
16
16
  :language="'JSON'"
17
- :prev="props.record[props.meta.resourceColumns.resourceDataColumnName].oldRecord"
18
- :current="props.record[props.meta.resourceColumns.resourceDataColumnName].newRecord"
17
+ :prev="JSON.stringify(JSON.parse(props.record[props.meta.resourceColumns.resourceDataColumnName]).oldRecord, null, 2)"
18
+ :current="JSON.stringify(JSON.parse(props.record[props.meta.resourceColumns.resourceDataColumnName]).newRecord, null, 2)"
19
19
  />
20
20
  </template>
21
21
 
@@ -36,7 +36,6 @@ export default class AuditLogPlugin extends AdminForthPlugin {
36
36
  'oldRecord': oldRecord || {},
37
37
  'newRecord': newRecord
38
38
  }
39
- // console.log('newData', newData)
40
39
  const record = {
41
40
  [this.options.resourceColumns.resourceIdColumnName]: resource.resourceId,
42
41
  [this.options.resourceColumns.resourceActionColumnName]: action,
@@ -157,7 +157,7 @@ class ExpressServer implements ExpressHttpServer {
157
157
  res.status(401).send('Unauthorized by AdminForth');
158
158
  return
159
159
  }
160
- const adminforthUser = await this.adminforth.auth.verify(jwt);
160
+ const adminforthUser = await this.adminforth.auth.verify(jwt, 'auth');
161
161
  if (!adminforthUser) {
162
162
  res.status(401).send('Unauthorized by AdminForth');
163
163
  } else {
@@ -101,8 +101,9 @@ export interface AdminForthClass {
101
101
  createResourceRecord(params: { resource: AdminForthResource, record: any, adminUser: AdminUser }): Promise<any>;
102
102
 
103
103
  auth: {
104
+ verify(jwt : string, mustHaveType: string): Promise<any>;
104
105
 
105
- verify(jwt : string): Promise<any>;
106
+ issueJWT(payload: Object, type: string): string;
106
107
  }
107
108
 
108
109
  /**