@kava/kava-api-core 1.0.0 → 1.0.2
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/.github/workflows/publish.yml +40 -0
- package/dist/{auth.util.d.ts → auth/auth.d.ts} +1 -5
- package/dist/{auth.util.js → auth/auth.js} +38 -30
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/{context.util.js → context/context.js} +1 -1
- package/dist/context/context.js.map +1 -0
- package/dist/context/index.d.ts +1 -0
- package/dist/context/index.js +2 -0
- package/dist/context/index.js.map +1 -0
- package/dist/{controller.util.js → controller/controller.js} +1 -1
- package/dist/controller/controller.js.map +1 -0
- package/dist/controller/index.d.ts +1 -0
- package/dist/controller/index.js +2 -0
- package/dist/controller/index.js.map +1 -0
- package/dist/{conversion.util.js → conversion/conversion.js} +1 -1
- package/dist/conversion/conversion.js.map +1 -0
- package/dist/conversion/index.d.ts +1 -0
- package/dist/conversion/index.js +2 -0
- package/dist/conversion/index.js.map +1 -0
- package/dist/{db.util.d.ts → db/db.d.ts} +9 -5
- package/dist/{db.util.js → db/db.js} +40 -29
- package/dist/db/db.js.map +1 -0
- package/dist/db/index.d.ts +1 -0
- package/dist/db/index.js +2 -0
- package/dist/db/index.js.map +1 -0
- package/dist/index.d.ts +14 -13
- package/dist/index.js +14 -13
- package/dist/index.js.map +1 -1
- package/dist/logger/index.d.ts +1 -0
- package/dist/logger/index.js +2 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/{logger.util.js → logger/logger.js} +16 -7
- package/dist/logger/logger.js.map +1 -0
- package/dist/mail/index.d.ts +1 -0
- package/dist/mail/index.js +2 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/{mail.util.js → mail/mail.js} +1 -1
- package/dist/mail/mail.js.map +1 -0
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/{middleware.util.js → middleware/middleware.js} +1 -1
- package/dist/middleware/middleware.js.map +1 -0
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.js +2 -0
- package/dist/model/index.js.map +1 -0
- package/dist/{model.util.js → model/model.js} +1 -1
- package/dist/model/model.js.map +1 -0
- package/dist/permission/index.d.ts +1 -0
- package/dist/permission/index.js +2 -0
- package/dist/permission/index.js.map +1 -0
- package/dist/{permission.util.js → permission/permission.js} +1 -1
- package/dist/permission/permission.js.map +1 -0
- package/dist/registry/index.d.ts +1 -0
- package/dist/registry/index.js +2 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/registry.d.ts +28 -0
- package/dist/registry/registry.js +19 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/route/index.d.ts +1 -0
- package/dist/route/index.js +2 -0
- package/dist/route/index.js.map +1 -0
- package/dist/{route.util.js → route/route.js} +1 -1
- package/dist/route/route.js.map +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/{storage.util.js → storage/storage.js} +2 -2
- package/dist/storage/storage.js.map +1 -0
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.js +2 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/{validation.util.js → validation/validation.js} +1 -1
- package/dist/validation/validation.js.map +1 -0
- package/package.json +2 -2
- package/src/{auth.util.ts → auth/auth.ts} +255 -241
- package/src/auth/index.ts +1 -0
- package/src/{context.util.ts → context/context.ts} +17 -17
- package/src/context/index.ts +1 -0
- package/src/{controller.util.ts → controller/controller.ts} +236 -236
- package/src/controller/index.ts +1 -0
- package/src/{conversion.util.ts → conversion/conversion.ts} +64 -64
- package/src/conversion/index.ts +1 -0
- package/src/{db.util.ts → db/db.ts} +420 -405
- package/src/db/index.ts +1 -0
- package/src/index.ts +14 -13
- package/src/logger/index.ts +1 -0
- package/src/{logger.util.ts → logger/logger.ts} +176 -169
- package/src/mail/index.ts +1 -0
- package/src/{mail.util.ts → mail/mail.ts} +85 -85
- package/src/middleware/index.ts +1 -0
- package/src/{middleware.util.ts → middleware/middleware.ts} +288 -288
- package/src/model/index.ts +1 -0
- package/src/{model.util.ts → model/model.ts} +2210 -2210
- package/src/permission/index.ts +1 -0
- package/src/{permission.util.ts → permission/permission.ts} +136 -136
- package/src/registry/index.ts +1 -0
- package/src/registry/registry.ts +37 -0
- package/src/route/index.ts +1 -0
- package/src/{route.util.ts → route/route.ts} +11 -11
- package/src/storage/index.ts +1 -0
- package/src/{storage.util.ts → storage/storage.ts} +101 -101
- package/src/validation/index.ts +1 -0
- package/src/{validation.util.ts → validation/validation.ts} +338 -338
- package/tsconfig.json +1 -1
- package/bun.lock +0 -160
- package/dist/auth.util.js.map +0 -1
- package/dist/context.util.js.map +0 -1
- package/dist/controller.util.js.map +0 -1
- package/dist/conversion.util.js.map +0 -1
- package/dist/db.util.js.map +0 -1
- package/dist/logger.util.js.map +0 -1
- package/dist/mail.util.js.map +0 -1
- package/dist/middleware.util.js.map +0 -1
- package/dist/model.util.js.map +0 -1
- package/dist/permission.util.js.map +0 -1
- package/dist/route.util.js.map +0 -1
- package/dist/storage.util.js.map +0 -1
- package/dist/validation.util.js.map +0 -1
- /package/dist/{context.util.d.ts → context/context.d.ts} +0 -0
- /package/dist/{controller.util.d.ts → controller/controller.d.ts} +0 -0
- /package/dist/{conversion.util.d.ts → conversion/conversion.d.ts} +0 -0
- /package/dist/{logger.util.d.ts → logger/logger.d.ts} +0 -0
- /package/dist/{mail.util.d.ts → mail/mail.d.ts} +0 -0
- /package/dist/{middleware.util.d.ts → middleware/middleware.d.ts} +0 -0
- /package/dist/{model.util.d.ts → model/model.d.ts} +0 -0
- /package/dist/{permission.util.d.ts → permission/permission.d.ts} +0 -0
- /package/dist/{route.util.d.ts → route/route.d.ts} +0 -0
- /package/dist/{storage.util.d.ts → storage/storage.d.ts} +0 -0
- /package/dist/{validation.util.d.ts → validation/validation.d.ts} +0 -0
|
@@ -1,242 +1,256 @@
|
|
|
1
|
-
import crypto from 'crypto'
|
|
2
|
-
import bcrypt from "bcrypt";
|
|
3
|
-
import { db } from '@utils'
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
await trx.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
return
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
import bcrypt from "bcrypt";
|
|
3
|
+
import { db } from '@utils'
|
|
4
|
+
import { registry } from '@utils/registry'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
// =====================================>
|
|
9
|
+
// ## Auth: User Access Token
|
|
10
|
+
// =====================================>
|
|
11
|
+
const TOKEN_PLAIN_LENGTH = 20
|
|
12
|
+
const AUTH_PERMISSION = process.env.AUTH_CACHE === "true"
|
|
13
|
+
const AUTH_CACHE = process.env.AUTH_CACHE === "true"
|
|
14
|
+
const AUTH_CACHE_TTL = Number(process.env.AUTH_CACHE_TTL || 600)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export const auth = {
|
|
19
|
+
|
|
20
|
+
// =====================================>
|
|
21
|
+
// ## Auth: create access token with user id
|
|
22
|
+
// =====================================>
|
|
23
|
+
async createAccessToken(userId: number, req: Request, permission: boolean = true) {
|
|
24
|
+
const plain = crypto.randomBytes(TOKEN_PLAIN_LENGTH).toString("hex")
|
|
25
|
+
const hash = await bcrypt.hash(plain, 10)
|
|
26
|
+
const agent = generateAgentId(req)
|
|
27
|
+
|
|
28
|
+
let permissions: string[] = []
|
|
29
|
+
if (AUTH_PERMISSION && permission) {
|
|
30
|
+
permissions = await getUserPermissions(userId)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const [row] = await db("user_access_tokens").insert({
|
|
34
|
+
user_id : userId,
|
|
35
|
+
token : hash,
|
|
36
|
+
agent : agent,
|
|
37
|
+
permissions : JSON.stringify(permissions),
|
|
38
|
+
created_at : new Date(),
|
|
39
|
+
}).returning(["id"])
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
token : `${row.id}|${plain}`,
|
|
43
|
+
tokenId : row.id,
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
// =====================================>
|
|
50
|
+
// ## Auth: delete access token with user id
|
|
51
|
+
// =====================================>
|
|
52
|
+
async revokeAccessToken(id: number) {
|
|
53
|
+
return db.table('user_access_tokens').where("id", id).delete()
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
// =====================================>
|
|
59
|
+
// ## Auth: verify access token
|
|
60
|
+
// =====================================>
|
|
61
|
+
async verifyAccessToken(token: string, req?: Request) {
|
|
62
|
+
if (!token.includes("|")) return null
|
|
63
|
+
|
|
64
|
+
const [tokenId, plain] = token.split("|", 2)
|
|
65
|
+
const agent = req ? generateAgentId(req) : ""
|
|
66
|
+
const ip = req ? getRequestIp(req) : ""
|
|
67
|
+
|
|
68
|
+
const cacheKey = `auth:token:${tokenId}`
|
|
69
|
+
|
|
70
|
+
if (AUTH_CACHE) {
|
|
71
|
+
const redis = registry.get('redis')
|
|
72
|
+
|
|
73
|
+
if (redis) {
|
|
74
|
+
const cached = await redis.get(cacheKey)
|
|
75
|
+
|
|
76
|
+
if (cached) {
|
|
77
|
+
const session = JSON.parse(cached)
|
|
78
|
+
|
|
79
|
+
if (session.agent !== agent) return null
|
|
80
|
+
|
|
81
|
+
return session
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const tokenRecord = await db("user_access_tokens").where("id", tokenId).first()
|
|
87
|
+
|
|
88
|
+
if (!tokenRecord) return null
|
|
89
|
+
if (tokenRecord.agent !== agent) return null
|
|
90
|
+
|
|
91
|
+
const valid = await bcrypt.compare(plain, tokenRecord.token)
|
|
92
|
+
if (!valid) return null
|
|
93
|
+
|
|
94
|
+
await db("user_access_tokens").where("id", tokenRecord.id).update({ last_used_at: new Date(), last_used_ip: ip })
|
|
95
|
+
|
|
96
|
+
const user = await db("users").where("id", tokenRecord.user_id).first()
|
|
97
|
+
|
|
98
|
+
if (AUTH_CACHE) {
|
|
99
|
+
const redis = registry.get('redis')
|
|
100
|
+
if (redis) {
|
|
101
|
+
await redis.setex(
|
|
102
|
+
cacheKey,
|
|
103
|
+
AUTH_CACHE_TTL,
|
|
104
|
+
JSON.stringify({
|
|
105
|
+
user : user,
|
|
106
|
+
agent : tokenRecord.agent,
|
|
107
|
+
permissions : tokenRecord.permission,
|
|
108
|
+
})
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return { user, token: tokenRecord, permissions: tokenRecord.permission }
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
// =====================================>
|
|
119
|
+
// ## Auth: create user mail token
|
|
120
|
+
// =====================================>
|
|
121
|
+
async createUserMailToken(userId: number) {
|
|
122
|
+
const token = Math.floor(100000 + Math.random() * 900000).toString()
|
|
123
|
+
const hash = crypto.createHash('sha256').update(token).digest('hex')
|
|
124
|
+
|
|
125
|
+
const trx = await db.transaction()
|
|
126
|
+
|
|
127
|
+
await trx.table('user_mail_tokens').insert({
|
|
128
|
+
user_id : userId,
|
|
129
|
+
token : hash,
|
|
130
|
+
created_at : new Date(),
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
const record = await trx.table('user_mail_tokens').orderBy('id', 'desc').first()
|
|
134
|
+
|
|
135
|
+
await trx.commit()
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
token : token,
|
|
139
|
+
tokenId : record.id
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
// =====================================>
|
|
146
|
+
// ## Auth: Verify user mail token
|
|
147
|
+
// =====================================>
|
|
148
|
+
async verifyUserMailToken(userId: number, token: string) {
|
|
149
|
+
const hashedToken = crypto.createHash("sha256").update(token).digest("hex");
|
|
150
|
+
|
|
151
|
+
const record = await db.table("user_mail_tokens")
|
|
152
|
+
.where("user_id", userId)
|
|
153
|
+
.whereNull("used_at")
|
|
154
|
+
.orderBy("id", "desc")
|
|
155
|
+
.first();
|
|
156
|
+
|
|
157
|
+
if (!record) return false
|
|
158
|
+
|
|
159
|
+
if (record.token !== hashedToken) return false;
|
|
160
|
+
|
|
161
|
+
const createdAt = new Date(record.created_at);
|
|
162
|
+
const now = new Date();
|
|
163
|
+
const diffMinutes = (now.getTime() - createdAt.getTime()) / (1000 * 60);
|
|
164
|
+
|
|
165
|
+
if (diffMinutes > 10) return false;
|
|
166
|
+
|
|
167
|
+
return true;
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
// =====================================>
|
|
173
|
+
// ## Auth: list user sessions
|
|
174
|
+
// =====================================>
|
|
175
|
+
async listUserSessions(userId: number, currentTokenId?: number) {
|
|
176
|
+
const rows = await db("user_access_tokens").select(["id", "agent", "created_at", "last_used_at", "last_used_ip","expired_at"]).where("user_id", userId).orderBy("last_used_at", "desc")
|
|
177
|
+
|
|
178
|
+
return rows.map(r => ({
|
|
179
|
+
...r,
|
|
180
|
+
is_active : r.revoked_at === null,
|
|
181
|
+
is_current : r.id === currentTokenId,
|
|
182
|
+
}))
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
// =====================================>
|
|
188
|
+
// ## Auth: revalidate user permission
|
|
189
|
+
// =====================================>
|
|
190
|
+
revalidateUserPermissions: revalidateUserPermissions,
|
|
191
|
+
revalidateUserPermissionsByRole: revalidateUserPermissionsByRole,
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
function generateAgentId(req: Request) {
|
|
197
|
+
const ua = req.headers.get("user-agent") ?? ""
|
|
198
|
+
const acc = req.headers.get("accept") ?? ""
|
|
199
|
+
|
|
200
|
+
return crypto.createHash("sha256").update(ua + acc).digest("hex")
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
function getRequestIp(req: Request) {
|
|
205
|
+
return (req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || req.headers.get("x-real-ip") || "unknown")
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
async function getUserPermissions(userId: number): Promise<string[]> {
|
|
210
|
+
const roleIds = await db("user_roles").where("user_id", userId).pluck("role_id")
|
|
211
|
+
|
|
212
|
+
if (roleIds.length === 0) return []
|
|
213
|
+
|
|
214
|
+
const rows = await db("permissions").whereIn("role_id", roleIds).pluck("permissions")
|
|
215
|
+
|
|
216
|
+
return Array.from(
|
|
217
|
+
new Set(
|
|
218
|
+
rows.flatMap(p => p ?? [])
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
async function revalidateUserPermissions(userId: number) {
|
|
225
|
+
const permissions = await getUserPermissions(userId)
|
|
226
|
+
|
|
227
|
+
const tokenIds = await db("user_access_tokens").where("user_id", userId).pluck("id")
|
|
228
|
+
|
|
229
|
+
if (tokenIds.length === 0) return
|
|
230
|
+
|
|
231
|
+
await db("user_access_tokens").whereIn("id", tokenIds).update({
|
|
232
|
+
permissions : JSON.stringify(permissions),
|
|
233
|
+
updated_at : new Date(),
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
if (AUTH_CACHE) {
|
|
237
|
+
const redis = registry.get('redis')
|
|
238
|
+
if (redis) {
|
|
239
|
+
await Promise.all(
|
|
240
|
+
tokenIds.map(id => redis.del(`auth:token:${id}`))
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
async function revalidateUserPermissionsByRole(roleId: number) {
|
|
248
|
+
const userIds = await db("user_roles").where("role_id", roleId).pluck("user_id")
|
|
249
|
+
|
|
250
|
+
const queue = registry.get('queue')
|
|
251
|
+
if (queue) {
|
|
252
|
+
for (const userId of userIds) {
|
|
253
|
+
await queue.add("auth:revalidate-permission", { userId })
|
|
254
|
+
}
|
|
255
|
+
}
|
|
242
256
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./auth";
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
2
|
-
|
|
3
|
-
export type AppContext = {
|
|
4
|
-
user_id?: number,
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const storage = new AsyncLocalStorage<AppContext>()
|
|
8
|
-
|
|
9
|
-
export const context = {
|
|
10
|
-
run<T>(ctx: AppContext, fn: () => T) {
|
|
11
|
-
return storage.run(ctx, fn)
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
get<K extends keyof AppContext>(key: K): AppContext[K] {
|
|
15
|
-
return storage.getStore()?.[key]
|
|
16
|
-
},
|
|
17
|
-
}
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
2
|
+
|
|
3
|
+
export type AppContext = {
|
|
4
|
+
user_id?: number,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const storage = new AsyncLocalStorage<AppContext>()
|
|
8
|
+
|
|
9
|
+
export const context = {
|
|
10
|
+
run<T>(ctx: AppContext, fn: () => T) {
|
|
11
|
+
return storage.run(ctx, fn)
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
get<K extends keyof AppContext>(key: K): AppContext[K] {
|
|
15
|
+
return storage.getStore()?.[key]
|
|
16
|
+
},
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./context";
|