@develit-io/backend-sdk 7.0.0 → 7.0.1
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 +3 -16
- package/dist/index.d.ts +3 -16
- package/dist/index.mjs +117 -430
- package/dist/middlewares.d.mts +15 -0
- package/dist/middlewares.d.ts +15 -0
- package/dist/middlewares.mjs +230 -0
- package/dist/shared/backend-sdk.CgM_2r0b.mjs +98 -0
- package/package.json +6 -1
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,6 @@ import * as drizzle_orm from 'drizzle-orm';
|
|
|
2
2
|
import { ExtractTablesWithRelations, DBQueryConfig, BuildQueryResult, AnyColumn } from 'drizzle-orm';
|
|
3
3
|
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
|
4
4
|
import { AnySQLiteTable } from 'drizzle-orm/sqlite-core';
|
|
5
|
-
import { MiddlewareHandler } from 'hono/types';
|
|
6
5
|
import { z as z$1 } from 'zod';
|
|
7
6
|
import * as z from 'zod/v4/core';
|
|
8
7
|
import { ContentfulStatusCode, SuccessStatusCode } from 'hono/utils/http-status';
|
|
@@ -35,7 +34,7 @@ declare const bankAccount: {
|
|
|
35
34
|
swiftBic: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"swift_bic", [string, ...string[]], number | undefined>;
|
|
36
35
|
bicCor: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"bic_cor", [string, ...string[]], number | undefined>;
|
|
37
36
|
currency: drizzle_orm.NotNull<drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"currency", ["CZK" | "EUR" | "USD" | "PLN" | "RON" | "GBP" | "RUB" | "HUF" | "CHF" | "DKK" | "SEK" | "HRK" | "NOK" | "BGN" | "TRY" | "AUD" | "CAD" | "JPY" | "CNY" | "INR" | "BRL" | "MXN" | "ZAR" | "SGD" | "HKD" | "KRW" | "MYR" | "THB" | "IDR" | "PHP" | "AED" | "SAR" | "ILS" | "EGP" | "NGN" | "PKR" | "COP" | "CLP" | "PEN" | "VND" | "KZT" | "UAH" | "BTC" | "ETH" | "ADA" | "DOT" | "ATOM" | "XRP" | "LTC" | "SOL" | "DOGE" | "MATIC" | "AVAX", ...("CZK" | "EUR" | "USD" | "PLN" | "RON" | "GBP" | "RUB" | "HUF" | "CHF" | "DKK" | "SEK" | "HRK" | "NOK" | "BGN" | "TRY" | "AUD" | "CAD" | "JPY" | "CNY" | "INR" | "BRL" | "MXN" | "ZAR" | "SGD" | "HKD" | "KRW" | "MYR" | "THB" | "IDR" | "PHP" | "AED" | "SAR" | "ILS" | "EGP" | "NGN" | "PKR" | "COP" | "CLP" | "PEN" | "VND" | "KZT" | "UAH" | "BTC" | "ETH" | "ADA" | "DOT" | "ATOM" | "XRP" | "LTC" | "SOL" | "DOGE" | "MATIC" | "AVAX")[]], number | undefined>>;
|
|
38
|
-
countryCode: drizzle_orm.NotNull<drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"country_code", ["AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "
|
|
37
|
+
countryCode: drizzle_orm.NotNull<drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"country_code", ["EC" | "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GR" | "GD" | "GP" | "GU" | "GT" | "GN" | "GW" | "GY" | "HT" | "HN" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IM" | "IL" | "IT" | "CI" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "XK" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LI" | "LT" | "LU" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MQ" | "MR" | "MU" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "NA" | "NP" | "NL" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "NO" | "OM" | "PK" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "CG" | "RE" | "RO" | "RU" | "RW" | "BL" | "KN" | "LC" | "MF" | "VC" | "WS" | "SM" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SZ" | "SE" | "CH" | "TW" | "TJ" | "TZ" | "TH" | "TG" | "TO" | "TT" | "TN" | "TR" | "TM" | "UM" | "VI" | "UG" | "UA" | "AE" | "GB" | "UZ" | "VU" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW", ...("EC" | "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GR" | "GD" | "GP" | "GU" | "GT" | "GN" | "GW" | "GY" | "HT" | "HN" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IM" | "IL" | "IT" | "CI" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "XK" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LI" | "LT" | "LU" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MQ" | "MR" | "MU" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "NA" | "NP" | "NL" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "NO" | "OM" | "PK" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "CG" | "RE" | "RO" | "RU" | "RW" | "BL" | "KN" | "LC" | "MF" | "VC" | "WS" | "SM" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SZ" | "SE" | "CH" | "TW" | "TJ" | "TZ" | "TH" | "TG" | "TO" | "TT" | "TN" | "TR" | "TM" | "UM" | "VI" | "UG" | "UA" | "AE" | "GB" | "UZ" | "VU" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW")[]], number | undefined>>;
|
|
39
38
|
routingNumber: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"routing_number", [string, ...string[]], number | undefined>;
|
|
40
39
|
sortCode: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"sort_code", [string, ...string[]], number | undefined>;
|
|
41
40
|
clabe: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"clabe", [string, ...string[]], number | undefined>;
|
|
@@ -67,18 +66,6 @@ declare const composeWranglerBase: ({ project, name, }: {
|
|
|
67
66
|
keep_vars: boolean;
|
|
68
67
|
};
|
|
69
68
|
|
|
70
|
-
declare const idempotency: <T extends {
|
|
71
|
-
IDEMPOTENCY_KV: KVNamespace;
|
|
72
|
-
}>() => MiddlewareHandler;
|
|
73
|
-
|
|
74
|
-
declare const jwt: <TAuthService, TJwtPayload>() => MiddlewareHandler;
|
|
75
|
-
|
|
76
|
-
declare const ip: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
77
|
-
|
|
78
|
-
declare const logger: () => MiddlewareHandler;
|
|
79
|
-
|
|
80
|
-
declare const signature: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
81
|
-
|
|
82
69
|
interface AuditLogPayload<T> {
|
|
83
70
|
action: T;
|
|
84
71
|
actorId: string;
|
|
@@ -208,6 +195,7 @@ declare const bankAccountMetadataSchema: z$1.ZodObject<{
|
|
|
208
195
|
AVAX: "AVAX";
|
|
209
196
|
}>>;
|
|
210
197
|
country: z$1.ZodOptional<z$1.ZodEnum<{
|
|
198
|
+
EC: "EC";
|
|
211
199
|
AF: "AF";
|
|
212
200
|
AL: "AL";
|
|
213
201
|
DZ: "DZ";
|
|
@@ -261,7 +249,6 @@ declare const bankAccountMetadataSchema: z$1.ZodObject<{
|
|
|
261
249
|
DM: "DM";
|
|
262
250
|
DO: "DO";
|
|
263
251
|
TL: "TL";
|
|
264
|
-
EC: "EC";
|
|
265
252
|
EG: "EG";
|
|
266
253
|
SV: "SV";
|
|
267
254
|
GQ: "GQ";
|
|
@@ -834,5 +821,5 @@ interface WithRetryCounterOptions {
|
|
|
834
821
|
type AsyncMethod<TArgs extends unknown[] = unknown[], TResult = unknown> = (...args: TArgs) => Promise<TResult>;
|
|
835
822
|
declare function cloudflareQueue<TArgs extends unknown[] = unknown[], TResult = unknown>(options: WithRetryCounterOptions): (target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<AsyncMethod<TArgs, TResult>>) => void;
|
|
836
823
|
|
|
837
|
-
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, createSignatureKeyPair, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema,
|
|
824
|
+
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, createSignatureKeyPair, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, isInternalError, paginationQuerySchema, paginationSchema, service, signPayload, useFetch, useResult, useResultSync, uuidv4, verifyPayloadSignature };
|
|
838
825
|
export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, AuthUser, BankAccountMetadata, BaseEvent, BuildSearchOptions, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, UserRole, UserVariables, ValidatedInput };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import * as drizzle_orm from 'drizzle-orm';
|
|
|
2
2
|
import { ExtractTablesWithRelations, DBQueryConfig, BuildQueryResult, AnyColumn } from 'drizzle-orm';
|
|
3
3
|
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
|
4
4
|
import { AnySQLiteTable } from 'drizzle-orm/sqlite-core';
|
|
5
|
-
import { MiddlewareHandler } from 'hono/types';
|
|
6
5
|
import { z as z$1 } from 'zod';
|
|
7
6
|
import * as z from 'zod/v4/core';
|
|
8
7
|
import { ContentfulStatusCode, SuccessStatusCode } from 'hono/utils/http-status';
|
|
@@ -35,7 +34,7 @@ declare const bankAccount: {
|
|
|
35
34
|
swiftBic: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"swift_bic", [string, ...string[]], number | undefined>;
|
|
36
35
|
bicCor: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"bic_cor", [string, ...string[]], number | undefined>;
|
|
37
36
|
currency: drizzle_orm.NotNull<drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"currency", ["CZK" | "EUR" | "USD" | "PLN" | "RON" | "GBP" | "RUB" | "HUF" | "CHF" | "DKK" | "SEK" | "HRK" | "NOK" | "BGN" | "TRY" | "AUD" | "CAD" | "JPY" | "CNY" | "INR" | "BRL" | "MXN" | "ZAR" | "SGD" | "HKD" | "KRW" | "MYR" | "THB" | "IDR" | "PHP" | "AED" | "SAR" | "ILS" | "EGP" | "NGN" | "PKR" | "COP" | "CLP" | "PEN" | "VND" | "KZT" | "UAH" | "BTC" | "ETH" | "ADA" | "DOT" | "ATOM" | "XRP" | "LTC" | "SOL" | "DOGE" | "MATIC" | "AVAX", ...("CZK" | "EUR" | "USD" | "PLN" | "RON" | "GBP" | "RUB" | "HUF" | "CHF" | "DKK" | "SEK" | "HRK" | "NOK" | "BGN" | "TRY" | "AUD" | "CAD" | "JPY" | "CNY" | "INR" | "BRL" | "MXN" | "ZAR" | "SGD" | "HKD" | "KRW" | "MYR" | "THB" | "IDR" | "PHP" | "AED" | "SAR" | "ILS" | "EGP" | "NGN" | "PKR" | "COP" | "CLP" | "PEN" | "VND" | "KZT" | "UAH" | "BTC" | "ETH" | "ADA" | "DOT" | "ATOM" | "XRP" | "LTC" | "SOL" | "DOGE" | "MATIC" | "AVAX")[]], number | undefined>>;
|
|
38
|
-
countryCode: drizzle_orm.NotNull<drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"country_code", ["AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "
|
|
37
|
+
countryCode: drizzle_orm.NotNull<drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"country_code", ["EC" | "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GR" | "GD" | "GP" | "GU" | "GT" | "GN" | "GW" | "GY" | "HT" | "HN" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IM" | "IL" | "IT" | "CI" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "XK" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LI" | "LT" | "LU" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MQ" | "MR" | "MU" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "NA" | "NP" | "NL" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "NO" | "OM" | "PK" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "CG" | "RE" | "RO" | "RU" | "RW" | "BL" | "KN" | "LC" | "MF" | "VC" | "WS" | "SM" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SZ" | "SE" | "CH" | "TW" | "TJ" | "TZ" | "TH" | "TG" | "TO" | "TT" | "TN" | "TR" | "TM" | "UM" | "VI" | "UG" | "UA" | "AE" | "GB" | "UZ" | "VU" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW", ...("EC" | "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BO" | "BQ" | "BA" | "BW" | "BR" | "IO" | "VG" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "CF" | "TD" | "CL" | "CN" | "CO" | "KM" | "CK" | "CR" | "HR" | "CW" | "CY" | "CZ" | "CD" | "DK" | "DJ" | "DM" | "DO" | "TL" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GR" | "GD" | "GP" | "GU" | "GT" | "GN" | "GW" | "GY" | "HT" | "HN" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IM" | "IL" | "IT" | "CI" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "XK" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LI" | "LT" | "LU" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MQ" | "MR" | "MU" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "NA" | "NP" | "NL" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "NO" | "OM" | "PK" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "CG" | "RE" | "RO" | "RU" | "RW" | "BL" | "KN" | "LC" | "MF" | "VC" | "WS" | "SM" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SZ" | "SE" | "CH" | "TW" | "TJ" | "TZ" | "TH" | "TG" | "TO" | "TT" | "TN" | "TR" | "TM" | "UM" | "VI" | "UG" | "UA" | "AE" | "GB" | "UZ" | "VU" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW")[]], number | undefined>>;
|
|
39
38
|
routingNumber: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"routing_number", [string, ...string[]], number | undefined>;
|
|
40
39
|
sortCode: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"sort_code", [string, ...string[]], number | undefined>;
|
|
41
40
|
clabe: drizzle_orm_sqlite_core.SQLiteTextBuilderInitial<"clabe", [string, ...string[]], number | undefined>;
|
|
@@ -67,18 +66,6 @@ declare const composeWranglerBase: ({ project, name, }: {
|
|
|
67
66
|
keep_vars: boolean;
|
|
68
67
|
};
|
|
69
68
|
|
|
70
|
-
declare const idempotency: <T extends {
|
|
71
|
-
IDEMPOTENCY_KV: KVNamespace;
|
|
72
|
-
}>() => MiddlewareHandler;
|
|
73
|
-
|
|
74
|
-
declare const jwt: <TAuthService, TJwtPayload>() => MiddlewareHandler;
|
|
75
|
-
|
|
76
|
-
declare const ip: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
77
|
-
|
|
78
|
-
declare const logger: () => MiddlewareHandler;
|
|
79
|
-
|
|
80
|
-
declare const signature: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
81
|
-
|
|
82
69
|
interface AuditLogPayload<T> {
|
|
83
70
|
action: T;
|
|
84
71
|
actorId: string;
|
|
@@ -208,6 +195,7 @@ declare const bankAccountMetadataSchema: z$1.ZodObject<{
|
|
|
208
195
|
AVAX: "AVAX";
|
|
209
196
|
}>>;
|
|
210
197
|
country: z$1.ZodOptional<z$1.ZodEnum<{
|
|
198
|
+
EC: "EC";
|
|
211
199
|
AF: "AF";
|
|
212
200
|
AL: "AL";
|
|
213
201
|
DZ: "DZ";
|
|
@@ -261,7 +249,6 @@ declare const bankAccountMetadataSchema: z$1.ZodObject<{
|
|
|
261
249
|
DM: "DM";
|
|
262
250
|
DO: "DO";
|
|
263
251
|
TL: "TL";
|
|
264
|
-
EC: "EC";
|
|
265
252
|
EG: "EG";
|
|
266
253
|
SV: "SV";
|
|
267
254
|
GQ: "GQ";
|
|
@@ -834,5 +821,5 @@ interface WithRetryCounterOptions {
|
|
|
834
821
|
type AsyncMethod<TArgs extends unknown[] = unknown[], TResult = unknown> = (...args: TArgs) => Promise<TResult>;
|
|
835
822
|
declare function cloudflareQueue<TArgs extends unknown[] = unknown[], TResult = unknown>(options: WithRetryCounterOptions): (target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<AsyncMethod<TArgs, TResult>>) => void;
|
|
836
823
|
|
|
837
|
-
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, createSignatureKeyPair, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema,
|
|
824
|
+
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, createSignatureKeyPair, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, isInternalError, paginationQuerySchema, paginationSchema, service, signPayload, useFetch, useResult, useResultSync, uuidv4, verifyPayloadSignature };
|
|
838
825
|
export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, AuthUser, BankAccountMetadata, BaseEvent, BuildSearchOptions, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, UserRole, UserVariables, ValidatedInput };
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { sql, or, inArray, eq, gte, lte, and } from 'drizzle-orm';
|
|
2
2
|
import { integer, text } from 'drizzle-orm/sqlite-core';
|
|
3
3
|
import { COUNTRY_CODES_2, CURRENCY_CODES, BANK_CODES } from '@develit-io/general-codes';
|
|
4
|
-
import { createMiddleware } from 'hono/factory';
|
|
5
|
-
import { HTTPException } from 'hono/http-exception';
|
|
6
|
-
import { createError } from 'h3';
|
|
7
4
|
import { z as z$1 } from 'zod';
|
|
5
|
+
import * as z from 'zod/v4/core';
|
|
6
|
+
import { createError } from 'h3';
|
|
8
7
|
import 'cloudflare';
|
|
9
8
|
import fs from 'node:fs';
|
|
10
|
-
import crypto$1
|
|
9
|
+
import crypto$1 from 'node:crypto';
|
|
11
10
|
import path from 'node:path';
|
|
12
11
|
import { parse } from 'comment-json';
|
|
13
|
-
|
|
12
|
+
export { c as createSignatureKeyPair, s as signPayload, v as verifyPayloadSignature } from './shared/backend-sdk.CgM_2r0b.mjs';
|
|
14
13
|
import superjson from 'superjson';
|
|
15
14
|
|
|
16
15
|
const ENVIRONMENT = ["dev", "test", "staging", "production"];
|
|
@@ -76,34 +75,119 @@ const composeWranglerBase = ({
|
|
|
76
75
|
};
|
|
77
76
|
};
|
|
78
77
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
78
|
+
const ibanSchema = z$1.string().min(1).regex(/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/, {
|
|
79
|
+
message: "Invalid IBAN format"
|
|
80
|
+
});
|
|
81
|
+
const bicSchema = z$1.string().min(1).regex(/^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/, {
|
|
82
|
+
message: "Invalid SWIFT/BIC format"
|
|
83
|
+
});
|
|
84
|
+
const bankAccountMetadataSchema = z$1.object({
|
|
85
|
+
id: z$1.string().optional(),
|
|
86
|
+
number: z$1.string().optional(),
|
|
87
|
+
bankCode: z$1.enum(BANK_CODES).optional(),
|
|
88
|
+
holderName: z$1.string().optional(),
|
|
89
|
+
iban: ibanSchema.optional(),
|
|
90
|
+
address: z$1.string().optional(),
|
|
91
|
+
swiftBic: bicSchema.optional(),
|
|
92
|
+
bicCor: bicSchema.optional(),
|
|
93
|
+
currency: z$1.enum(CURRENCY_CODES).optional(),
|
|
94
|
+
country: z$1.enum(COUNTRY_CODES_2).optional(),
|
|
95
|
+
routingNumber: z$1.string().optional(),
|
|
96
|
+
// US
|
|
97
|
+
sortCode: z$1.string().optional(),
|
|
98
|
+
// UK
|
|
99
|
+
clabe: z$1.string().optional(),
|
|
100
|
+
// Mexico
|
|
101
|
+
bsb: z$1.string().optional(),
|
|
102
|
+
// Australia
|
|
103
|
+
brBankNumber: z$1.string().optional()
|
|
104
|
+
// Brazil
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const paginationQuerySchema = new z.$ZodObject({
|
|
108
|
+
type: "object",
|
|
109
|
+
shape: {
|
|
110
|
+
page: new z.$ZodDefault({
|
|
111
|
+
type: "default",
|
|
112
|
+
innerType: new z.$ZodNumber({
|
|
113
|
+
type: "number",
|
|
114
|
+
coerce: true
|
|
115
|
+
}),
|
|
116
|
+
defaultValue: () => 1
|
|
117
|
+
}),
|
|
118
|
+
limit: new z.$ZodDefault({
|
|
119
|
+
type: "default",
|
|
120
|
+
innerType: new z.$ZodNumber({
|
|
121
|
+
type: "number",
|
|
122
|
+
coerce: true
|
|
123
|
+
}),
|
|
124
|
+
defaultValue: () => 20
|
|
125
|
+
}),
|
|
126
|
+
sort: new z.$ZodDefault({
|
|
127
|
+
type: "default",
|
|
128
|
+
innerType: new z.$ZodObject({
|
|
129
|
+
type: "object",
|
|
130
|
+
shape: {
|
|
131
|
+
column: new z.$ZodDefault({
|
|
132
|
+
type: "default",
|
|
133
|
+
innerType: new z.$ZodEnum({
|
|
134
|
+
type: "enum",
|
|
135
|
+
entries: {
|
|
136
|
+
createdAt: "createdAt",
|
|
137
|
+
updatedAt: "updatedAt",
|
|
138
|
+
deletedAt: "deletedAt"
|
|
139
|
+
}
|
|
140
|
+
}),
|
|
141
|
+
defaultValue: () => "updatedAt"
|
|
142
|
+
}),
|
|
143
|
+
direction: new z.$ZodDefault({
|
|
144
|
+
type: "default",
|
|
145
|
+
innerType: new z.$ZodEnum({
|
|
146
|
+
type: "enum",
|
|
147
|
+
entries: {
|
|
148
|
+
asc: "asc",
|
|
149
|
+
desc: "desc"
|
|
150
|
+
}
|
|
151
|
+
}),
|
|
152
|
+
defaultValue: () => "desc"
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
}),
|
|
156
|
+
defaultValue: () => ({ column: "updatedAt", direction: "desc" })
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
const paginationSchema = new z.$ZodObject({
|
|
161
|
+
type: "object",
|
|
162
|
+
shape: {
|
|
163
|
+
page: new z.$ZodNumber({
|
|
164
|
+
type: "number"
|
|
165
|
+
}),
|
|
166
|
+
limit: new z.$ZodNumber({
|
|
167
|
+
type: "number"
|
|
168
|
+
}),
|
|
169
|
+
sort: new z.$ZodObject({
|
|
170
|
+
type: "object",
|
|
171
|
+
shape: {
|
|
172
|
+
column: new z.$ZodEnum({
|
|
173
|
+
type: "enum",
|
|
174
|
+
entries: {
|
|
175
|
+
createdAt: "createdAt",
|
|
176
|
+
updatedAt: "updatedAt",
|
|
177
|
+
deletedAt: "deletedAt"
|
|
178
|
+
}
|
|
179
|
+
}),
|
|
180
|
+
direction: new z.$ZodEnum({
|
|
181
|
+
type: "enum",
|
|
182
|
+
entries: {
|
|
183
|
+
asc: "asc",
|
|
184
|
+
desc: "desc"
|
|
185
|
+
}
|
|
186
|
+
})
|
|
99
187
|
}
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
});
|
|
104
|
-
await next();
|
|
105
|
-
});
|
|
106
|
-
};
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
});
|
|
107
191
|
|
|
108
192
|
const handleActionResponse = ({
|
|
109
193
|
error,
|
|
@@ -263,16 +347,6 @@ function createAuditLogWriter(table) {
|
|
|
263
347
|
};
|
|
264
348
|
}
|
|
265
349
|
|
|
266
|
-
const validateBearerScheme = (header) => {
|
|
267
|
-
return header.startsWith("Bearer ") && header.length > 7 && !header.slice(7).includes(" ");
|
|
268
|
-
};
|
|
269
|
-
const extractBearerToken = (header) => {
|
|
270
|
-
return header.slice(7).trim();
|
|
271
|
-
};
|
|
272
|
-
const validateBearerToken = (bearerToken) => {
|
|
273
|
-
return z$1.jwt().safeParse(bearerToken).success;
|
|
274
|
-
};
|
|
275
|
-
|
|
276
350
|
function first(rows) {
|
|
277
351
|
return rows.length > 0 ? rows[0] : void 0;
|
|
278
352
|
}
|
|
@@ -509,108 +583,6 @@ async function useFetch(url, { parseAs = "json", ...options } = {}) {
|
|
|
509
583
|
return [body, null];
|
|
510
584
|
}
|
|
511
585
|
|
|
512
|
-
const logRequest = (log) => {
|
|
513
|
-
console.log("REQUEST | An incoming request has been recorded.", log);
|
|
514
|
-
};
|
|
515
|
-
const logResponse = (log) => {
|
|
516
|
-
console.log(`RESPONSE | An outgoing response has been recorded.`, log);
|
|
517
|
-
};
|
|
518
|
-
|
|
519
|
-
const createSignatureKeyPair = async () => {
|
|
520
|
-
const { publicKey, privateKey } = await subtle.generateKey(
|
|
521
|
-
{
|
|
522
|
-
name: "RSASSA-PKCS1-v1_5",
|
|
523
|
-
modulusLength: 4096,
|
|
524
|
-
publicExponent: new Uint8Array([1, 0, 1]),
|
|
525
|
-
hash: "SHA-256"
|
|
526
|
-
},
|
|
527
|
-
true,
|
|
528
|
-
["sign", "verify"]
|
|
529
|
-
);
|
|
530
|
-
const exportedPublicKey = await subtle.exportKey("spki", publicKey);
|
|
531
|
-
const exportedPrivateKey = await subtle.exportKey("pkcs8", privateKey);
|
|
532
|
-
return {
|
|
533
|
-
publicKey: Buffer.from(exportedPublicKey).toString("base64"),
|
|
534
|
-
privateKey: Buffer.from(exportedPrivateKey).toString("base64")
|
|
535
|
-
};
|
|
536
|
-
};
|
|
537
|
-
const signPayload = async ({
|
|
538
|
-
payload,
|
|
539
|
-
privateKey
|
|
540
|
-
}) => {
|
|
541
|
-
const binaryPrivateKey = Uint8Array.from(
|
|
542
|
-
atob(privateKey),
|
|
543
|
-
(c) => c.charCodeAt(0)
|
|
544
|
-
);
|
|
545
|
-
const importedPrivateKey = await crypto.subtle.importKey(
|
|
546
|
-
"pkcs8",
|
|
547
|
-
binaryPrivateKey,
|
|
548
|
-
{
|
|
549
|
-
name: "RSASSA-PKCS1-v1_5",
|
|
550
|
-
hash: "SHA-256"
|
|
551
|
-
},
|
|
552
|
-
false,
|
|
553
|
-
["sign"]
|
|
554
|
-
);
|
|
555
|
-
const encodedPayload = new TextEncoder().encode(payload);
|
|
556
|
-
const signature = await crypto.subtle.sign(
|
|
557
|
-
{
|
|
558
|
-
name: "RSASSA-PKCS1-v1_5"
|
|
559
|
-
},
|
|
560
|
-
importedPrivateKey,
|
|
561
|
-
encodedPayload
|
|
562
|
-
);
|
|
563
|
-
const base64Signature = btoa(
|
|
564
|
-
String.fromCharCode(...new Uint8Array(signature))
|
|
565
|
-
);
|
|
566
|
-
return base64Signature;
|
|
567
|
-
};
|
|
568
|
-
const algParams = {
|
|
569
|
-
RSA: {
|
|
570
|
-
name: "RSASSA-PKCS1-v1_5",
|
|
571
|
-
hash: { name: "SHA-256" }
|
|
572
|
-
},
|
|
573
|
-
EC: {
|
|
574
|
-
name: "ECDSA",
|
|
575
|
-
namedCurve: "P-256"
|
|
576
|
-
},
|
|
577
|
-
HMAC: {
|
|
578
|
-
name: "HMAC",
|
|
579
|
-
hash: { name: "SHA-256" }
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
const verifyPayloadSignature = async ({
|
|
583
|
-
signature,
|
|
584
|
-
data,
|
|
585
|
-
publicKey,
|
|
586
|
-
algorithm = "RSA"
|
|
587
|
-
}) => {
|
|
588
|
-
const binaryPublicKey = Uint8Array.from(
|
|
589
|
-
atob(publicKey),
|
|
590
|
-
(c) => c.charCodeAt(0)
|
|
591
|
-
);
|
|
592
|
-
const format = algorithm === "HMAC" ? "raw" : "spki";
|
|
593
|
-
const importedPublicKey = await crypto.subtle.importKey(
|
|
594
|
-
format,
|
|
595
|
-
binaryPublicKey,
|
|
596
|
-
algParams[algorithm],
|
|
597
|
-
false,
|
|
598
|
-
["verify"]
|
|
599
|
-
);
|
|
600
|
-
const encodedPayload = new TextEncoder().encode(data);
|
|
601
|
-
const decodedSignature = Uint8Array.from(
|
|
602
|
-
atob(signature),
|
|
603
|
-
(c) => c.charCodeAt(0)
|
|
604
|
-
);
|
|
605
|
-
const isValid = await crypto.subtle.verify(
|
|
606
|
-
algParams[algorithm],
|
|
607
|
-
importedPublicKey,
|
|
608
|
-
decodedSignature,
|
|
609
|
-
encodedPayload
|
|
610
|
-
);
|
|
611
|
-
return isValid;
|
|
612
|
-
};
|
|
613
|
-
|
|
614
586
|
const calculateExponentialBackoff = (attempts, baseDelaySeconds) => {
|
|
615
587
|
return baseDelaySeconds ** attempts;
|
|
616
588
|
};
|
|
@@ -627,291 +599,6 @@ const getSecret = async (secretName, env) => {
|
|
|
627
599
|
return await secret.get();
|
|
628
600
|
};
|
|
629
601
|
|
|
630
|
-
const jwt = () => {
|
|
631
|
-
return createMiddleware(async (context, next) => {
|
|
632
|
-
const authorizationHeader = context.req.header("Authorization");
|
|
633
|
-
if (!authorizationHeader) {
|
|
634
|
-
throw new HTTPException(401, {
|
|
635
|
-
message: `The 'Authorization' header must exist and must have a value.`
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
if (!validateBearerScheme(authorizationHeader)) {
|
|
639
|
-
throw new HTTPException(401, {
|
|
640
|
-
message: `The 'Authorization' header value must use the Bearer scheme.`
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
const bearerToken = extractBearerToken(authorizationHeader);
|
|
644
|
-
if (!validateBearerToken(bearerToken)) {
|
|
645
|
-
throw new HTTPException(401, {
|
|
646
|
-
message: `The Bearer token in the 'Authorization' header value must be a JWT.`
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
const authService = context.env.AUTH_SERVICE;
|
|
650
|
-
const { data, error } = await authService.verifyAccessToken({
|
|
651
|
-
accessToken: bearerToken
|
|
652
|
-
});
|
|
653
|
-
if (!data || error) {
|
|
654
|
-
throw new HTTPException(401, {
|
|
655
|
-
message: "The JWT must contain valid user information."
|
|
656
|
-
});
|
|
657
|
-
}
|
|
658
|
-
const rawUserMetaDataString = data.payload.user.rawUserMetaData;
|
|
659
|
-
const rawUserMetaData = rawUserMetaDataString ? JSON.parse(rawUserMetaDataString) : null;
|
|
660
|
-
const organizationId = rawUserMetaData?.organizationId ?? null;
|
|
661
|
-
if (!organizationId) {
|
|
662
|
-
throw new HTTPException(422, {
|
|
663
|
-
message: "User data integrity check failed."
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
context.set("user", {
|
|
667
|
-
email: data.payload.user.email,
|
|
668
|
-
role: data.payload.user.role,
|
|
669
|
-
organizationId
|
|
670
|
-
});
|
|
671
|
-
context.set("jwt", data.payload);
|
|
672
|
-
await next();
|
|
673
|
-
});
|
|
674
|
-
};
|
|
675
|
-
|
|
676
|
-
const ip = () => {
|
|
677
|
-
return createMiddleware(async (context, next) => {
|
|
678
|
-
if (!["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
|
|
679
|
-
const requestIp = context.req.header("cf-connecting-ip") || context.req.header("x-forwarded-for");
|
|
680
|
-
if (!requestIp) {
|
|
681
|
-
throw new HTTPException(401, {
|
|
682
|
-
message: "Failed to retrieve request IP address."
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
const user = context.get("user");
|
|
686
|
-
if (!user.organizationId) {
|
|
687
|
-
throw new HTTPException(401, {
|
|
688
|
-
message: "Failed to retrieve request organization ID."
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
const organizationService = context.env.ORGANIZATION_SERVICE;
|
|
692
|
-
const { data: organization, error } = await organizationService.getOrganization({
|
|
693
|
-
organizationId: user.organizationId
|
|
694
|
-
});
|
|
695
|
-
if (!organization || error) {
|
|
696
|
-
throw new HTTPException(404, {
|
|
697
|
-
message: "Failed to retrieve organization."
|
|
698
|
-
});
|
|
699
|
-
}
|
|
700
|
-
if (organization.ipAuthorization) {
|
|
701
|
-
if (!organization.authorizedIps.map((ip2) => ip2.ip).includes(requestIp)) {
|
|
702
|
-
throw new HTTPException(404, {
|
|
703
|
-
message: "Forbidden"
|
|
704
|
-
});
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
await next();
|
|
709
|
-
});
|
|
710
|
-
};
|
|
711
|
-
|
|
712
|
-
const composeRequestLog = async (request) => {
|
|
713
|
-
return {
|
|
714
|
-
method: request.method,
|
|
715
|
-
path: request.path,
|
|
716
|
-
query: request.query(),
|
|
717
|
-
headers: request.header(),
|
|
718
|
-
body: await request.json().catch(() => null)
|
|
719
|
-
};
|
|
720
|
-
};
|
|
721
|
-
const composeResponseLog = async (response, method, path) => {
|
|
722
|
-
return {
|
|
723
|
-
method,
|
|
724
|
-
path,
|
|
725
|
-
status: response.status,
|
|
726
|
-
statusText: response.statusText,
|
|
727
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
728
|
-
body: await response.json().catch(() => null)
|
|
729
|
-
};
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
const logger = () => {
|
|
733
|
-
return createMiddleware(async (context, next) => {
|
|
734
|
-
const requestLog = await composeRequestLog(context.req);
|
|
735
|
-
logRequest(requestLog);
|
|
736
|
-
await next();
|
|
737
|
-
const response = context.res.clone();
|
|
738
|
-
const responseLog = await composeResponseLog(
|
|
739
|
-
response,
|
|
740
|
-
context.req.method,
|
|
741
|
-
context.req.url
|
|
742
|
-
);
|
|
743
|
-
logResponse(responseLog);
|
|
744
|
-
});
|
|
745
|
-
};
|
|
746
|
-
|
|
747
|
-
const signature = () => {
|
|
748
|
-
return createMiddleware(async (context, next) => {
|
|
749
|
-
if (!["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
|
|
750
|
-
const signatureHeader = context.req.header("X-Signature");
|
|
751
|
-
if (!signatureHeader) {
|
|
752
|
-
throw new HTTPException(401, {
|
|
753
|
-
message: `The 'X-Signature' header must exist and must have a value.`
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
|
-
const signatureKeyHeader = context.req.header("X-Signature-Key");
|
|
757
|
-
if (!signatureKeyHeader) {
|
|
758
|
-
throw new HTTPException(401, {
|
|
759
|
-
message: `The 'X-Signature-Key' header must exist and must have a value.`
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
const payload = JSON.stringify(await context.req.json().catch(() => null));
|
|
763
|
-
const user = context.get("user");
|
|
764
|
-
if (!user.organizationId) {
|
|
765
|
-
throw new HTTPException(401, {
|
|
766
|
-
message: "Failed to retrieve request organization ID."
|
|
767
|
-
});
|
|
768
|
-
}
|
|
769
|
-
const organizationService = context.env.ORGANIZATION_SERVICE;
|
|
770
|
-
const { data: organization, error } = await organizationService.getOrganization({
|
|
771
|
-
organizationId: user.organizationId
|
|
772
|
-
});
|
|
773
|
-
if (!organization || error) {
|
|
774
|
-
throw new HTTPException(404, {
|
|
775
|
-
message: "Failed to retrieve organization."
|
|
776
|
-
});
|
|
777
|
-
}
|
|
778
|
-
const signatureKey = organization.signatureKeys.filter(
|
|
779
|
-
(signatureKey2) => signatureKey2.name === signatureKeyHeader
|
|
780
|
-
)[0];
|
|
781
|
-
if (!signatureKey) {
|
|
782
|
-
throw new HTTPException(404, {
|
|
783
|
-
message: "Signature key not found."
|
|
784
|
-
});
|
|
785
|
-
}
|
|
786
|
-
const isVerified = await verifyPayloadSignature({
|
|
787
|
-
signature: signatureHeader,
|
|
788
|
-
publicKey: signatureKey.publicKey,
|
|
789
|
-
data: payload
|
|
790
|
-
});
|
|
791
|
-
if (!isVerified) {
|
|
792
|
-
throw new HTTPException(401, {
|
|
793
|
-
message: "Invalid signature key or signature."
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
await next();
|
|
798
|
-
});
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
const ibanSchema = z$1.string().min(1).regex(/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/, {
|
|
802
|
-
message: "Invalid IBAN format"
|
|
803
|
-
});
|
|
804
|
-
const bicSchema = z$1.string().min(1).regex(/^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/, {
|
|
805
|
-
message: "Invalid SWIFT/BIC format"
|
|
806
|
-
});
|
|
807
|
-
const bankAccountMetadataSchema = z$1.object({
|
|
808
|
-
id: z$1.string().optional(),
|
|
809
|
-
number: z$1.string().optional(),
|
|
810
|
-
bankCode: z$1.enum(BANK_CODES).optional(),
|
|
811
|
-
holderName: z$1.string().optional(),
|
|
812
|
-
iban: ibanSchema.optional(),
|
|
813
|
-
address: z$1.string().optional(),
|
|
814
|
-
swiftBic: bicSchema.optional(),
|
|
815
|
-
bicCor: bicSchema.optional(),
|
|
816
|
-
currency: z$1.enum(CURRENCY_CODES).optional(),
|
|
817
|
-
country: z$1.enum(COUNTRY_CODES_2).optional(),
|
|
818
|
-
routingNumber: z$1.string().optional(),
|
|
819
|
-
// US
|
|
820
|
-
sortCode: z$1.string().optional(),
|
|
821
|
-
// UK
|
|
822
|
-
clabe: z$1.string().optional(),
|
|
823
|
-
// Mexico
|
|
824
|
-
bsb: z$1.string().optional(),
|
|
825
|
-
// Australia
|
|
826
|
-
brBankNumber: z$1.string().optional()
|
|
827
|
-
// Brazil
|
|
828
|
-
});
|
|
829
|
-
|
|
830
|
-
const paginationQuerySchema = new z.$ZodObject({
|
|
831
|
-
type: "object",
|
|
832
|
-
shape: {
|
|
833
|
-
page: new z.$ZodDefault({
|
|
834
|
-
type: "default",
|
|
835
|
-
innerType: new z.$ZodNumber({
|
|
836
|
-
type: "number",
|
|
837
|
-
coerce: true
|
|
838
|
-
}),
|
|
839
|
-
defaultValue: () => 1
|
|
840
|
-
}),
|
|
841
|
-
limit: new z.$ZodDefault({
|
|
842
|
-
type: "default",
|
|
843
|
-
innerType: new z.$ZodNumber({
|
|
844
|
-
type: "number",
|
|
845
|
-
coerce: true
|
|
846
|
-
}),
|
|
847
|
-
defaultValue: () => 20
|
|
848
|
-
}),
|
|
849
|
-
sort: new z.$ZodDefault({
|
|
850
|
-
type: "default",
|
|
851
|
-
innerType: new z.$ZodObject({
|
|
852
|
-
type: "object",
|
|
853
|
-
shape: {
|
|
854
|
-
column: new z.$ZodDefault({
|
|
855
|
-
type: "default",
|
|
856
|
-
innerType: new z.$ZodEnum({
|
|
857
|
-
type: "enum",
|
|
858
|
-
entries: {
|
|
859
|
-
createdAt: "createdAt",
|
|
860
|
-
updatedAt: "updatedAt",
|
|
861
|
-
deletedAt: "deletedAt"
|
|
862
|
-
}
|
|
863
|
-
}),
|
|
864
|
-
defaultValue: () => "updatedAt"
|
|
865
|
-
}),
|
|
866
|
-
direction: new z.$ZodDefault({
|
|
867
|
-
type: "default",
|
|
868
|
-
innerType: new z.$ZodEnum({
|
|
869
|
-
type: "enum",
|
|
870
|
-
entries: {
|
|
871
|
-
asc: "asc",
|
|
872
|
-
desc: "desc"
|
|
873
|
-
}
|
|
874
|
-
}),
|
|
875
|
-
defaultValue: () => "desc"
|
|
876
|
-
})
|
|
877
|
-
}
|
|
878
|
-
}),
|
|
879
|
-
defaultValue: () => ({ column: "updatedAt", direction: "desc" })
|
|
880
|
-
})
|
|
881
|
-
}
|
|
882
|
-
});
|
|
883
|
-
const paginationSchema = new z.$ZodObject({
|
|
884
|
-
type: "object",
|
|
885
|
-
shape: {
|
|
886
|
-
page: new z.$ZodNumber({
|
|
887
|
-
type: "number"
|
|
888
|
-
}),
|
|
889
|
-
limit: new z.$ZodNumber({
|
|
890
|
-
type: "number"
|
|
891
|
-
}),
|
|
892
|
-
sort: new z.$ZodObject({
|
|
893
|
-
type: "object",
|
|
894
|
-
shape: {
|
|
895
|
-
column: new z.$ZodEnum({
|
|
896
|
-
type: "enum",
|
|
897
|
-
entries: {
|
|
898
|
-
createdAt: "createdAt",
|
|
899
|
-
updatedAt: "updatedAt",
|
|
900
|
-
deletedAt: "deletedAt"
|
|
901
|
-
}
|
|
902
|
-
}),
|
|
903
|
-
direction: new z.$ZodEnum({
|
|
904
|
-
type: "enum",
|
|
905
|
-
entries: {
|
|
906
|
-
asc: "asc",
|
|
907
|
-
desc: "desc"
|
|
908
|
-
}
|
|
909
|
-
})
|
|
910
|
-
}
|
|
911
|
-
})
|
|
912
|
-
}
|
|
913
|
-
});
|
|
914
|
-
|
|
915
602
|
const service = (serviceName) => {
|
|
916
603
|
return function(constructor) {
|
|
917
604
|
return class extends constructor {
|
|
@@ -1052,4 +739,4 @@ function develitWorker(Worker) {
|
|
|
1052
739
|
return DevelitWorker;
|
|
1053
740
|
}
|
|
1054
741
|
|
|
1055
|
-
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError,
|
|
742
|
+
export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, buildMultiFilterConditions, buildRangeFilterConditions, buildSearchConditions, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, isInternalError, paginationQuerySchema, paginationSchema, service, useFetch, useResult, useResultSync, uuidv4 };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MiddlewareHandler } from 'hono/types';
|
|
2
|
+
|
|
3
|
+
declare const idempotency: <T extends {
|
|
4
|
+
IDEMPOTENCY_KV: KVNamespace;
|
|
5
|
+
}>() => MiddlewareHandler;
|
|
6
|
+
|
|
7
|
+
declare const jwt: <TAuthService, TJwtPayload>() => MiddlewareHandler;
|
|
8
|
+
|
|
9
|
+
declare const ip: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
10
|
+
|
|
11
|
+
declare const logger: () => MiddlewareHandler;
|
|
12
|
+
|
|
13
|
+
declare const signature: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
14
|
+
|
|
15
|
+
export { idempotency, ip, jwt, logger, signature };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { MiddlewareHandler } from 'hono/types';
|
|
2
|
+
|
|
3
|
+
declare const idempotency: <T extends {
|
|
4
|
+
IDEMPOTENCY_KV: KVNamespace;
|
|
5
|
+
}>() => MiddlewareHandler;
|
|
6
|
+
|
|
7
|
+
declare const jwt: <TAuthService, TJwtPayload>() => MiddlewareHandler;
|
|
8
|
+
|
|
9
|
+
declare const ip: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
10
|
+
|
|
11
|
+
declare const logger: () => MiddlewareHandler;
|
|
12
|
+
|
|
13
|
+
declare const signature: <TOrganizationService, TJwtPayload>() => MiddlewareHandler;
|
|
14
|
+
|
|
15
|
+
export { idempotency, ip, jwt, logger, signature };
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { createMiddleware } from 'hono/factory';
|
|
2
|
+
import { HTTPException } from 'hono/http-exception';
|
|
3
|
+
import 'h3';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import 'cloudflare';
|
|
6
|
+
import 'node:fs';
|
|
7
|
+
import 'node:crypto';
|
|
8
|
+
import 'node:path';
|
|
9
|
+
import 'comment-json';
|
|
10
|
+
import 'drizzle-orm';
|
|
11
|
+
import { v as verifyPayloadSignature } from './shared/backend-sdk.CgM_2r0b.mjs';
|
|
12
|
+
|
|
13
|
+
const validateBearerScheme = (header) => {
|
|
14
|
+
return header.startsWith("Bearer ") && header.length > 7 && !header.slice(7).includes(" ");
|
|
15
|
+
};
|
|
16
|
+
const extractBearerToken = (header) => {
|
|
17
|
+
return header.slice(7).trim();
|
|
18
|
+
};
|
|
19
|
+
const validateBearerToken = (bearerToken) => {
|
|
20
|
+
return z.jwt().safeParse(bearerToken).success;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const logRequest = (log) => {
|
|
24
|
+
console.log("REQUEST | An incoming request has been recorded.", log);
|
|
25
|
+
};
|
|
26
|
+
const logResponse = (log) => {
|
|
27
|
+
console.log(`RESPONSE | An outgoing response has been recorded.`, log);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const idempotency = () => {
|
|
31
|
+
return createMiddleware(async (context, next) => {
|
|
32
|
+
const idempotencyKeyHeader = context.req.header("X-Idempotency-Key");
|
|
33
|
+
if (!idempotencyKeyHeader) {
|
|
34
|
+
throw new HTTPException(401, {
|
|
35
|
+
message: `The 'X-Idempotency-Key' header must exist and must have a value.`
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const existingIdempotencyRecord = await context.env.IDEMPOTENCY_KV.get(idempotencyKeyHeader);
|
|
39
|
+
if (existingIdempotencyRecord) {
|
|
40
|
+
throw new HTTPException(409, {
|
|
41
|
+
message: "The identical request has already been processed. The idempotency key is not unique."
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
await context.env.IDEMPOTENCY_KV.put(
|
|
45
|
+
idempotencyKeyHeader,
|
|
46
|
+
idempotencyKeyHeader,
|
|
47
|
+
{
|
|
48
|
+
expirationTtl: 60 * 60 * 24 * 3
|
|
49
|
+
// 3 days
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
context.set("idempotency", {
|
|
53
|
+
key: idempotencyKeyHeader
|
|
54
|
+
});
|
|
55
|
+
await next();
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const jwt = () => {
|
|
60
|
+
return createMiddleware(async (context, next) => {
|
|
61
|
+
const authorizationHeader = context.req.header("Authorization");
|
|
62
|
+
if (!authorizationHeader) {
|
|
63
|
+
throw new HTTPException(401, {
|
|
64
|
+
message: `The 'Authorization' header must exist and must have a value.`
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (!validateBearerScheme(authorizationHeader)) {
|
|
68
|
+
throw new HTTPException(401, {
|
|
69
|
+
message: `The 'Authorization' header value must use the Bearer scheme.`
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const bearerToken = extractBearerToken(authorizationHeader);
|
|
73
|
+
if (!validateBearerToken(bearerToken)) {
|
|
74
|
+
throw new HTTPException(401, {
|
|
75
|
+
message: `The Bearer token in the 'Authorization' header value must be a JWT.`
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const authService = context.env.AUTH_SERVICE;
|
|
79
|
+
const { data, error } = await authService.verifyAccessToken({
|
|
80
|
+
accessToken: bearerToken
|
|
81
|
+
});
|
|
82
|
+
if (!data || error) {
|
|
83
|
+
throw new HTTPException(401, {
|
|
84
|
+
message: "The JWT must contain valid user information."
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const rawUserMetaDataString = data.payload.user.rawUserMetaData;
|
|
88
|
+
const rawUserMetaData = rawUserMetaDataString ? JSON.parse(rawUserMetaDataString) : null;
|
|
89
|
+
const organizationId = rawUserMetaData?.organizationId ?? null;
|
|
90
|
+
if (!organizationId) {
|
|
91
|
+
throw new HTTPException(422, {
|
|
92
|
+
message: "User data integrity check failed."
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
context.set("user", {
|
|
96
|
+
email: data.payload.user.email,
|
|
97
|
+
role: data.payload.user.role,
|
|
98
|
+
organizationId
|
|
99
|
+
});
|
|
100
|
+
context.set("jwt", data.payload);
|
|
101
|
+
await next();
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const ip = () => {
|
|
106
|
+
return createMiddleware(async (context, next) => {
|
|
107
|
+
if (!["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
|
|
108
|
+
const requestIp = context.req.header("cf-connecting-ip") || context.req.header("x-forwarded-for");
|
|
109
|
+
if (!requestIp) {
|
|
110
|
+
throw new HTTPException(401, {
|
|
111
|
+
message: "Failed to retrieve request IP address."
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const user = context.get("user");
|
|
115
|
+
if (!user.organizationId) {
|
|
116
|
+
throw new HTTPException(401, {
|
|
117
|
+
message: "Failed to retrieve request organization ID."
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const organizationService = context.env.ORGANIZATION_SERVICE;
|
|
121
|
+
const { data: organization, error } = await organizationService.getOrganization({
|
|
122
|
+
organizationId: user.organizationId
|
|
123
|
+
});
|
|
124
|
+
if (!organization || error) {
|
|
125
|
+
throw new HTTPException(404, {
|
|
126
|
+
message: "Failed to retrieve organization."
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (organization.ipAuthorization) {
|
|
130
|
+
if (!organization.authorizedIps.map((ip2) => ip2.ip).includes(requestIp)) {
|
|
131
|
+
throw new HTTPException(404, {
|
|
132
|
+
message: "Forbidden"
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
await next();
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const composeRequestLog = async (request) => {
|
|
142
|
+
return {
|
|
143
|
+
method: request.method,
|
|
144
|
+
path: request.path,
|
|
145
|
+
query: request.query(),
|
|
146
|
+
headers: request.header(),
|
|
147
|
+
body: await request.json().catch(() => null)
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
const composeResponseLog = async (response, method, path) => {
|
|
151
|
+
return {
|
|
152
|
+
method,
|
|
153
|
+
path,
|
|
154
|
+
status: response.status,
|
|
155
|
+
statusText: response.statusText,
|
|
156
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
157
|
+
body: await response.json().catch(() => null)
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const logger = () => {
|
|
162
|
+
return createMiddleware(async (context, next) => {
|
|
163
|
+
const requestLog = await composeRequestLog(context.req);
|
|
164
|
+
logRequest(requestLog);
|
|
165
|
+
await next();
|
|
166
|
+
const response = context.res.clone();
|
|
167
|
+
const responseLog = await composeResponseLog(
|
|
168
|
+
response,
|
|
169
|
+
context.req.method,
|
|
170
|
+
context.req.url
|
|
171
|
+
);
|
|
172
|
+
logResponse(responseLog);
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const signature = () => {
|
|
177
|
+
return createMiddleware(async (context, next) => {
|
|
178
|
+
if (!["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
|
|
179
|
+
const signatureHeader = context.req.header("X-Signature");
|
|
180
|
+
if (!signatureHeader) {
|
|
181
|
+
throw new HTTPException(401, {
|
|
182
|
+
message: `The 'X-Signature' header must exist and must have a value.`
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
const signatureKeyHeader = context.req.header("X-Signature-Key");
|
|
186
|
+
if (!signatureKeyHeader) {
|
|
187
|
+
throw new HTTPException(401, {
|
|
188
|
+
message: `The 'X-Signature-Key' header must exist and must have a value.`
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
const payload = JSON.stringify(await context.req.json().catch(() => null));
|
|
192
|
+
const user = context.get("user");
|
|
193
|
+
if (!user.organizationId) {
|
|
194
|
+
throw new HTTPException(401, {
|
|
195
|
+
message: "Failed to retrieve request organization ID."
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const organizationService = context.env.ORGANIZATION_SERVICE;
|
|
199
|
+
const { data: organization, error } = await organizationService.getOrganization({
|
|
200
|
+
organizationId: user.organizationId
|
|
201
|
+
});
|
|
202
|
+
if (!organization || error) {
|
|
203
|
+
throw new HTTPException(404, {
|
|
204
|
+
message: "Failed to retrieve organization."
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
const signatureKey = organization.signatureKeys.filter(
|
|
208
|
+
(signatureKey2) => signatureKey2.name === signatureKeyHeader
|
|
209
|
+
)[0];
|
|
210
|
+
if (!signatureKey) {
|
|
211
|
+
throw new HTTPException(404, {
|
|
212
|
+
message: "Signature key not found."
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
const isVerified = await verifyPayloadSignature({
|
|
216
|
+
signature: signatureHeader,
|
|
217
|
+
publicKey: signatureKey.publicKey,
|
|
218
|
+
data: payload
|
|
219
|
+
});
|
|
220
|
+
if (!isVerified) {
|
|
221
|
+
throw new HTTPException(401, {
|
|
222
|
+
message: "Invalid signature key or signature."
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
await next();
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export { idempotency, ip, jwt, logger, signature };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { subtle } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
const createSignatureKeyPair = async () => {
|
|
4
|
+
const { publicKey, privateKey } = await subtle.generateKey(
|
|
5
|
+
{
|
|
6
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
7
|
+
modulusLength: 4096,
|
|
8
|
+
publicExponent: new Uint8Array([1, 0, 1]),
|
|
9
|
+
hash: "SHA-256"
|
|
10
|
+
},
|
|
11
|
+
true,
|
|
12
|
+
["sign", "verify"]
|
|
13
|
+
);
|
|
14
|
+
const exportedPublicKey = await subtle.exportKey("spki", publicKey);
|
|
15
|
+
const exportedPrivateKey = await subtle.exportKey("pkcs8", privateKey);
|
|
16
|
+
return {
|
|
17
|
+
publicKey: Buffer.from(exportedPublicKey).toString("base64"),
|
|
18
|
+
privateKey: Buffer.from(exportedPrivateKey).toString("base64")
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
const signPayload = async ({
|
|
22
|
+
payload,
|
|
23
|
+
privateKey
|
|
24
|
+
}) => {
|
|
25
|
+
const binaryPrivateKey = Uint8Array.from(
|
|
26
|
+
atob(privateKey),
|
|
27
|
+
(c) => c.charCodeAt(0)
|
|
28
|
+
);
|
|
29
|
+
const importedPrivateKey = await crypto.subtle.importKey(
|
|
30
|
+
"pkcs8",
|
|
31
|
+
binaryPrivateKey,
|
|
32
|
+
{
|
|
33
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
34
|
+
hash: "SHA-256"
|
|
35
|
+
},
|
|
36
|
+
false,
|
|
37
|
+
["sign"]
|
|
38
|
+
);
|
|
39
|
+
const encodedPayload = new TextEncoder().encode(payload);
|
|
40
|
+
const signature = await crypto.subtle.sign(
|
|
41
|
+
{
|
|
42
|
+
name: "RSASSA-PKCS1-v1_5"
|
|
43
|
+
},
|
|
44
|
+
importedPrivateKey,
|
|
45
|
+
encodedPayload
|
|
46
|
+
);
|
|
47
|
+
const base64Signature = btoa(
|
|
48
|
+
String.fromCharCode(...new Uint8Array(signature))
|
|
49
|
+
);
|
|
50
|
+
return base64Signature;
|
|
51
|
+
};
|
|
52
|
+
const algParams = {
|
|
53
|
+
RSA: {
|
|
54
|
+
name: "RSASSA-PKCS1-v1_5",
|
|
55
|
+
hash: { name: "SHA-256" }
|
|
56
|
+
},
|
|
57
|
+
EC: {
|
|
58
|
+
name: "ECDSA",
|
|
59
|
+
namedCurve: "P-256"
|
|
60
|
+
},
|
|
61
|
+
HMAC: {
|
|
62
|
+
name: "HMAC",
|
|
63
|
+
hash: { name: "SHA-256" }
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const verifyPayloadSignature = async ({
|
|
67
|
+
signature,
|
|
68
|
+
data,
|
|
69
|
+
publicKey,
|
|
70
|
+
algorithm = "RSA"
|
|
71
|
+
}) => {
|
|
72
|
+
const binaryPublicKey = Uint8Array.from(
|
|
73
|
+
atob(publicKey),
|
|
74
|
+
(c) => c.charCodeAt(0)
|
|
75
|
+
);
|
|
76
|
+
const format = algorithm === "HMAC" ? "raw" : "spki";
|
|
77
|
+
const importedPublicKey = await crypto.subtle.importKey(
|
|
78
|
+
format,
|
|
79
|
+
binaryPublicKey,
|
|
80
|
+
algParams[algorithm],
|
|
81
|
+
false,
|
|
82
|
+
["verify"]
|
|
83
|
+
);
|
|
84
|
+
const encodedPayload = new TextEncoder().encode(data);
|
|
85
|
+
const decodedSignature = Uint8Array.from(
|
|
86
|
+
atob(signature),
|
|
87
|
+
(c) => c.charCodeAt(0)
|
|
88
|
+
);
|
|
89
|
+
const isValid = await crypto.subtle.verify(
|
|
90
|
+
algParams[algorithm],
|
|
91
|
+
importedPublicKey,
|
|
92
|
+
decodedSignature,
|
|
93
|
+
encodedPayload
|
|
94
|
+
);
|
|
95
|
+
return isValid;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export { createSignatureKeyPair as c, signPayload as s, verifyPayloadSignature as v };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@develit-io/backend-sdk",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.1",
|
|
4
4
|
"description": "Develit Backend SDK",
|
|
5
5
|
"author": "Develit.io",
|
|
6
6
|
"license": "ISC",
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"import": "./dist/index.mjs",
|
|
23
23
|
"default": "./dist/index.mjs"
|
|
24
24
|
},
|
|
25
|
+
"./middlewares": {
|
|
26
|
+
"types": "./dist/middlewares.d.ts",
|
|
27
|
+
"import": "./dist/middlewares.mjs",
|
|
28
|
+
"default": "./dist/middlewares.mjs"
|
|
29
|
+
},
|
|
25
30
|
"./package.json": "./package.json"
|
|
26
31
|
},
|
|
27
32
|
"files": [
|