@develit-io/backend-sdk 9.3.0 → 9.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/dist/index.d.mts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/middlewares.d.mts +12 -1
- package/dist/middlewares.d.ts +12 -1
- package/dist/middlewares.mjs +67 -21
- package/dist/utils/signature.util.d.mts +5 -4
- package/dist/utils/signature.util.d.ts +5 -4
- package/dist/utils/signature.util.mjs +19 -18
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -447,11 +447,14 @@ interface CommandItem<TAuditAction = string> {
|
|
|
447
447
|
interface IdempotencyContextVariables {
|
|
448
448
|
key: string;
|
|
449
449
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
450
|
+
type IdentityContextVariables = {
|
|
451
|
+
user: {
|
|
452
|
+
id: string;
|
|
453
|
+
email: string;
|
|
454
|
+
role: string;
|
|
455
|
+
rawUserMetaData: string | null;
|
|
456
|
+
};
|
|
457
|
+
};
|
|
455
458
|
|
|
456
459
|
/**
|
|
457
460
|
* Utility type to infer possible relation includes (`with`) for a given table.
|
|
@@ -844,4 +847,4 @@ type AsyncMethod<TArgs extends unknown[] = unknown[], TResult = unknown> = (...a
|
|
|
844
847
|
declare function cloudflareQueue<TArgs extends unknown[] = unknown[], TResult = unknown>(options: WithRetryCounterOptions): (target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<AsyncMethod<TArgs, TResult>>) => void;
|
|
845
848
|
|
|
846
849
|
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, asNonEmpty, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, ibanSchema, isInternalError, nullToOptional, optionalToNull, paginationQuerySchema, paginationSchema, resolveColumn, service, useFetch, useResult, useResultSync, uuidv4, workflowInstanceStatusSchema };
|
|
847
|
-
export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, BankAccountMetadata, BaseEvent, BuildSearchOptions, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyContextVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, RequestLog, ResponseLog,
|
|
850
|
+
export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, BankAccountMetadata, BaseEvent, BuildSearchOptions, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyContextVariables, IdentityContextVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, RequestLog, ResponseLog, UserRole, ValidatedInput, WorkflowInstanceStatus };
|
package/dist/index.d.ts
CHANGED
|
@@ -447,11 +447,14 @@ interface CommandItem<TAuditAction = string> {
|
|
|
447
447
|
interface IdempotencyContextVariables {
|
|
448
448
|
key: string;
|
|
449
449
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
450
|
+
type IdentityContextVariables = {
|
|
451
|
+
user: {
|
|
452
|
+
id: string;
|
|
453
|
+
email: string;
|
|
454
|
+
role: string;
|
|
455
|
+
rawUserMetaData: string | null;
|
|
456
|
+
};
|
|
457
|
+
};
|
|
455
458
|
|
|
456
459
|
/**
|
|
457
460
|
* Utility type to infer possible relation includes (`with`) for a given table.
|
|
@@ -844,4 +847,4 @@ type AsyncMethod<TArgs extends unknown[] = unknown[], TResult = unknown> = (...a
|
|
|
844
847
|
declare function cloudflareQueue<TArgs extends unknown[] = unknown[], TResult = unknown>(options: WithRetryCounterOptions): (target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<AsyncMethod<TArgs, TResult>>) => void;
|
|
845
848
|
|
|
846
849
|
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, asNonEmpty, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, ibanSchema, isInternalError, nullToOptional, optionalToNull, paginationQuerySchema, paginationSchema, resolveColumn, service, useFetch, useResult, useResultSync, uuidv4, workflowInstanceStatusSchema };
|
|
847
|
-
export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, BankAccountMetadata, BaseEvent, BuildSearchOptions, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyContextVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, RequestLog, ResponseLog,
|
|
850
|
+
export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, BankAccountMetadata, BaseEvent, BuildSearchOptions, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyContextVariables, IdentityContextVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, RequestLog, ResponseLog, UserRole, ValidatedInput, WorkflowInstanceStatus };
|
package/dist/middlewares.d.mts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { MiddlewareHandler } from 'hono/types';
|
|
2
2
|
|
|
3
|
+
interface AccessMiddlewareOptions {
|
|
4
|
+
errorMessage?: string;
|
|
5
|
+
}
|
|
6
|
+
interface AccessRequest<TScope extends string = string> {
|
|
7
|
+
scope: TScope;
|
|
8
|
+
resourceId?: string;
|
|
9
|
+
resourcePath?: string;
|
|
10
|
+
}
|
|
11
|
+
type AccessRequestResolver<TScope extends string = string> = AccessRequest<TScope>[] | ((context: unknown) => AccessRequest<TScope>[]);
|
|
12
|
+
declare const access: <TScope extends string = string>(accessRequests: AccessRequestResolver<TScope>, options?: AccessMiddlewareOptions) => MiddlewareHandler;
|
|
13
|
+
|
|
3
14
|
declare const idempotency: () => MiddlewareHandler;
|
|
4
15
|
|
|
5
16
|
declare const jwt: () => MiddlewareHandler;
|
|
@@ -10,4 +21,4 @@ declare const logger: () => MiddlewareHandler;
|
|
|
10
21
|
|
|
11
22
|
declare const signature: () => MiddlewareHandler;
|
|
12
23
|
|
|
13
|
-
export { idempotency, ip, jwt, logger, signature };
|
|
24
|
+
export { access, idempotency, ip, jwt, logger, signature };
|
package/dist/middlewares.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { MiddlewareHandler } from 'hono/types';
|
|
2
2
|
|
|
3
|
+
interface AccessMiddlewareOptions {
|
|
4
|
+
errorMessage?: string;
|
|
5
|
+
}
|
|
6
|
+
interface AccessRequest<TScope extends string = string> {
|
|
7
|
+
scope: TScope;
|
|
8
|
+
resourceId?: string;
|
|
9
|
+
resourcePath?: string;
|
|
10
|
+
}
|
|
11
|
+
type AccessRequestResolver<TScope extends string = string> = AccessRequest<TScope>[] | ((context: unknown) => AccessRequest<TScope>[]);
|
|
12
|
+
declare const access: <TScope extends string = string>(accessRequests: AccessRequestResolver<TScope>, options?: AccessMiddlewareOptions) => MiddlewareHandler;
|
|
13
|
+
|
|
3
14
|
declare const idempotency: () => MiddlewareHandler;
|
|
4
15
|
|
|
5
16
|
declare const jwt: () => MiddlewareHandler;
|
|
@@ -10,4 +21,4 @@ declare const logger: () => MiddlewareHandler;
|
|
|
10
21
|
|
|
11
22
|
declare const signature: () => MiddlewareHandler;
|
|
12
23
|
|
|
13
|
-
export { idempotency, ip, jwt, logger, signature };
|
|
24
|
+
export { access, idempotency, ip, jwt, logger, signature };
|
package/dist/middlewares.mjs
CHANGED
|
@@ -33,6 +33,26 @@ const getRequestUserAgent = (request) => {
|
|
|
33
33
|
return request.header("user-agent") || "UNKNOWN";
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
const access = (accessRequests, options = {}) => {
|
|
37
|
+
return createMiddleware(async (context, next) => {
|
|
38
|
+
if (!context.env.MIDDLEWARE_ACCESS_DISABLED) {
|
|
39
|
+
const identity = context.get("identity");
|
|
40
|
+
const requests = typeof accessRequests === "function" ? accessRequests(context) : accessRequests;
|
|
41
|
+
const { data: verifyData, error: verifyError } = await context.env.RBAC_SERVICE.verifyAccess({
|
|
42
|
+
userId: identity.user.id,
|
|
43
|
+
accessRequests: requests,
|
|
44
|
+
jwt: identity
|
|
45
|
+
});
|
|
46
|
+
if (verifyError || !verifyData?.isVerified) {
|
|
47
|
+
throw new HTTPException(404, {
|
|
48
|
+
message: options.errorMessage || "Forbidden"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
await next();
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
36
56
|
const idempotency = () => {
|
|
37
57
|
return createMiddleware(async (context, next) => {
|
|
38
58
|
if (!context.env.MIDDLEWARE_IDEMPOTENCY_DISABLED) {
|
|
@@ -94,17 +114,13 @@ const jwt = () => {
|
|
|
94
114
|
}
|
|
95
115
|
const rawUserMetaDataString = data.payload.user.rawUserMetaData;
|
|
96
116
|
const rawUserMetaData = rawUserMetaDataString ? JSON.parse(rawUserMetaDataString) : null;
|
|
97
|
-
const
|
|
98
|
-
if (!
|
|
117
|
+
const identityId = rawUserMetaData.organizationId ?? rawUserMetaData.exchangeOfficeId;
|
|
118
|
+
if (!identityId) {
|
|
99
119
|
throw new HTTPException(422, {
|
|
100
120
|
message: "User data integrity check failed."
|
|
101
121
|
});
|
|
102
122
|
}
|
|
103
|
-
context.set("
|
|
104
|
-
email: data.payload.user.email,
|
|
105
|
-
role: data.payload.user.role,
|
|
106
|
-
organizationId
|
|
107
|
-
});
|
|
123
|
+
context.set("identity", data.payload);
|
|
108
124
|
}
|
|
109
125
|
await next();
|
|
110
126
|
});
|
|
@@ -114,14 +130,17 @@ const ip = () => {
|
|
|
114
130
|
return createMiddleware(async (context, next) => {
|
|
115
131
|
if (!context.env.MIDDLEWARE_IP_DISABLED) {
|
|
116
132
|
const requestIp = getRequestIpAddress(context.req);
|
|
117
|
-
const
|
|
118
|
-
|
|
133
|
+
const identityContext = context.get("identity");
|
|
134
|
+
const rawUserMetaDataString = identityContext.user.rawUserMetaData;
|
|
135
|
+
const rawUserMetaData = rawUserMetaDataString ? JSON.parse(rawUserMetaDataString) : null;
|
|
136
|
+
const organizationId = rawUserMetaData.organizationId;
|
|
137
|
+
if (!organizationId) {
|
|
119
138
|
throw new HTTPException(401, {
|
|
120
139
|
message: "Failed to retrieve request organization ID."
|
|
121
140
|
});
|
|
122
141
|
}
|
|
123
142
|
const { data: organization, error } = await context.env.ORGANIZATION_SERVICE.getOrganization({
|
|
124
|
-
organizationId
|
|
143
|
+
organizationId
|
|
125
144
|
});
|
|
126
145
|
if (!organization || error) {
|
|
127
146
|
throw new HTTPException(404, {
|
|
@@ -166,7 +185,15 @@ const logger = () => {
|
|
|
166
185
|
const requestLog = await composeRequestLog(context.req);
|
|
167
186
|
logRequest(requestLog);
|
|
168
187
|
if (!context.env.MIDDLEWARE_LOGGER_AUDITLOG_DISABLED) {
|
|
169
|
-
const
|
|
188
|
+
const identityContext = context.get("identity");
|
|
189
|
+
const rawUserMetaDataString = identityContext.user.rawUserMetaData;
|
|
190
|
+
const rawUserMetaData = rawUserMetaDataString ? JSON.parse(rawUserMetaDataString) : null;
|
|
191
|
+
const identityId = rawUserMetaData.organizationId ?? rawUserMetaData.exchangeOfficeId;
|
|
192
|
+
if (!identityId) {
|
|
193
|
+
throw new HTTPException(422, {
|
|
194
|
+
message: "User data integrity check failed."
|
|
195
|
+
});
|
|
196
|
+
}
|
|
170
197
|
const requestId = uuidv4();
|
|
171
198
|
context.set("auditLog", {
|
|
172
199
|
requestId
|
|
@@ -176,8 +203,12 @@ const logger = () => {
|
|
|
176
203
|
method: requestLog.method,
|
|
177
204
|
path: requestLog.path,
|
|
178
205
|
actor: {
|
|
179
|
-
email:
|
|
180
|
-
organizationId
|
|
206
|
+
email: identityContext.user.email || "NOT_AUTHORIZED",
|
|
207
|
+
...rawUserMetaData.organizationId ? {
|
|
208
|
+
organizationId: rawUserMetaData.organizationId || "NOT_AUTHORIZED"
|
|
209
|
+
} : rawUserMetaData.organizationId ? {
|
|
210
|
+
exchangeOfficeId: rawUserMetaData.exchangeOfficeId || "NOT_AUTHORIZED"
|
|
211
|
+
} : null
|
|
181
212
|
},
|
|
182
213
|
metadata: {
|
|
183
214
|
ip: getRequestIpAddress(context.req),
|
|
@@ -198,15 +229,27 @@ const logger = () => {
|
|
|
198
229
|
);
|
|
199
230
|
logResponse(responseLog);
|
|
200
231
|
if (!context.env.MIDDLEWARE_LOGGER_AUDITLOG_DISABLED) {
|
|
201
|
-
const
|
|
232
|
+
const identityContext = context.get("identity");
|
|
233
|
+
const rawUserMetaDataString = identityContext.user.rawUserMetaData;
|
|
234
|
+
const rawUserMetaData = rawUserMetaDataString ? JSON.parse(rawUserMetaDataString) : null;
|
|
235
|
+
const identityId = rawUserMetaData.organizationId ?? rawUserMetaData.exchangeOfficeId;
|
|
236
|
+
if (!identityId) {
|
|
237
|
+
throw new HTTPException(422, {
|
|
238
|
+
message: "User data integrity check failed."
|
|
239
|
+
});
|
|
240
|
+
}
|
|
202
241
|
const auditLogContext = context.get("auditLog");
|
|
203
242
|
await context.env.AUDITLOG_SERVICE.processLog({
|
|
204
243
|
type: "RESPONSE",
|
|
205
244
|
method: responseLog.method,
|
|
206
245
|
path: responseLog.path,
|
|
207
246
|
actor: {
|
|
208
|
-
email:
|
|
209
|
-
organizationId
|
|
247
|
+
email: identityContext.user.email || "NOT_AUTHORIZED",
|
|
248
|
+
...rawUserMetaData.organizationId ? {
|
|
249
|
+
organizationId: rawUserMetaData.organizationId || "NOT_AUTHORIZED"
|
|
250
|
+
} : rawUserMetaData.organizationId ? {
|
|
251
|
+
exchangeOfficeId: rawUserMetaData.exchangeOfficeId || "NOT_AUTHORIZED"
|
|
252
|
+
} : null
|
|
210
253
|
},
|
|
211
254
|
metadata: {
|
|
212
255
|
ip: getRequestIpAddress(context.req),
|
|
@@ -236,14 +279,17 @@ const signature = () => {
|
|
|
236
279
|
});
|
|
237
280
|
}
|
|
238
281
|
const payload = JSON.stringify(await context.req.json().catch(() => null));
|
|
239
|
-
const
|
|
240
|
-
|
|
282
|
+
const identityContext = context.get("identity");
|
|
283
|
+
const rawUserMetaDataString = identityContext.user.rawUserMetaData;
|
|
284
|
+
const rawUserMetaData = rawUserMetaDataString ? JSON.parse(rawUserMetaDataString) : null;
|
|
285
|
+
const identityId = rawUserMetaData.organizationId ?? rawUserMetaData.exchangeOfficeId;
|
|
286
|
+
if (!identityId) {
|
|
241
287
|
throw new HTTPException(401, {
|
|
242
|
-
message: "Failed to retrieve request
|
|
288
|
+
message: "Failed to retrieve request identity ID."
|
|
243
289
|
});
|
|
244
290
|
}
|
|
245
291
|
const { data: organization, error } = await context.env.ORGANIZATION_SERVICE.getOrganization({
|
|
246
|
-
organizationId:
|
|
292
|
+
organizationId: identityId
|
|
247
293
|
});
|
|
248
294
|
if (!organization || error) {
|
|
249
295
|
throw new HTTPException(404, {
|
|
@@ -273,4 +319,4 @@ const signature = () => {
|
|
|
273
319
|
});
|
|
274
320
|
};
|
|
275
321
|
|
|
276
|
-
export { idempotency, ip, jwt, logger, signature };
|
|
322
|
+
export { access, idempotency, ip, jwt, logger, signature };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
declare const createSignatureKeyPair: () => Promise<{
|
|
2
|
-
publicKey: string;
|
|
3
|
-
privateKey: string;
|
|
4
|
-
}>;
|
|
5
1
|
declare const signPayload: ({ payload, privateKey, }: {
|
|
6
2
|
payload: string;
|
|
7
3
|
privateKey: string;
|
|
8
4
|
}) => Promise<string>;
|
|
5
|
+
|
|
6
|
+
declare const createSignatureKeyPair: () => Promise<{
|
|
7
|
+
publicKey: string;
|
|
8
|
+
privateKey: string;
|
|
9
|
+
}>;
|
|
9
10
|
declare const algParams: {
|
|
10
11
|
[key: string]: {
|
|
11
12
|
name: string;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
declare const createSignatureKeyPair: () => Promise<{
|
|
2
|
-
publicKey: string;
|
|
3
|
-
privateKey: string;
|
|
4
|
-
}>;
|
|
5
1
|
declare const signPayload: ({ payload, privateKey, }: {
|
|
6
2
|
payload: string;
|
|
7
3
|
privateKey: string;
|
|
8
4
|
}) => Promise<string>;
|
|
5
|
+
|
|
6
|
+
declare const createSignatureKeyPair: () => Promise<{
|
|
7
|
+
publicKey: string;
|
|
8
|
+
privateKey: string;
|
|
9
|
+
}>;
|
|
9
10
|
declare const algParams: {
|
|
10
11
|
[key: string]: {
|
|
11
12
|
name: string;
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
const createSignatureKeyPair = async () => {
|
|
2
|
-
const { publicKey, privateKey } = await crypto.subtle.generateKey(
|
|
3
|
-
{
|
|
4
|
-
name: "RSASSA-PKCS1-v1_5",
|
|
5
|
-
modulusLength: 4096,
|
|
6
|
-
publicExponent: new Uint8Array([1, 0, 1]),
|
|
7
|
-
hash: "SHA-256"
|
|
8
|
-
},
|
|
9
|
-
true,
|
|
10
|
-
["sign", "verify"]
|
|
11
|
-
);
|
|
12
|
-
const exportedPublicKey = await crypto.subtle.exportKey("spki", publicKey);
|
|
13
|
-
const exportedPrivateKey = await crypto.subtle.exportKey("pkcs8", privateKey);
|
|
14
|
-
return {
|
|
15
|
-
publicKey: Buffer.from(exportedPublicKey).toString("base64"),
|
|
16
|
-
privateKey: Buffer.from(exportedPrivateKey).toString("base64")
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
1
|
const signPayload = async ({
|
|
20
2
|
payload,
|
|
21
3
|
privateKey
|
|
@@ -47,6 +29,25 @@ const signPayload = async ({
|
|
|
47
29
|
);
|
|
48
30
|
return base64Signature;
|
|
49
31
|
};
|
|
32
|
+
|
|
33
|
+
const createSignatureKeyPair = async () => {
|
|
34
|
+
const { publicKey, privateKey } = await crypto.subtle.generateKey(
|
|
35
|
+
{
|
|
36
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
37
|
+
modulusLength: 4096,
|
|
38
|
+
publicExponent: new Uint8Array([1, 0, 1]),
|
|
39
|
+
hash: "SHA-256"
|
|
40
|
+
},
|
|
41
|
+
true,
|
|
42
|
+
["sign", "verify"]
|
|
43
|
+
);
|
|
44
|
+
const exportedPublicKey = await crypto.subtle.exportKey("spki", publicKey);
|
|
45
|
+
const exportedPrivateKey = await crypto.subtle.exportKey("pkcs8", privateKey);
|
|
46
|
+
return {
|
|
47
|
+
publicKey: Buffer.from(exportedPublicKey).toString("base64"),
|
|
48
|
+
privateKey: Buffer.from(exportedPrivateKey).toString("base64")
|
|
49
|
+
};
|
|
50
|
+
};
|
|
50
51
|
const algParams = {
|
|
51
52
|
RSA: {
|
|
52
53
|
name: "RSASSA-PKCS1-v1_5",
|