@develit-io/backend-sdk 5.40.1 → 5.42.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 CHANGED
@@ -438,6 +438,17 @@ interface UseFetchOptions extends RequestInit {
438
438
  }
439
439
  declare function useFetch<T = unknown>(url: string, { parseAs, ...options }?: UseFetchOptions): Promise<Result<T>>;
440
440
 
441
+ declare const signPayload: ({ payload, privateKey, }: {
442
+ payload: string;
443
+ privateKey: string;
444
+ }) => Promise<string>;
445
+ declare const verifyPayloadSignature: ({ signature, data, publicKey, algorithm, }: {
446
+ signature: string;
447
+ data: string;
448
+ publicKey: string;
449
+ algorithm?: "RSA" | "EC" | "HMAC";
450
+ }) => Promise<boolean>;
451
+
441
452
  declare const calculateExponentialBackoff: (attempts: number, baseDelaySeconds: number) => number;
442
453
 
443
454
  declare const RPCResponse: {
@@ -527,5 +538,5 @@ interface WithRetryCounterOptions {
527
538
  type AsyncMethod<TArgs extends unknown[] = unknown[], TResult = unknown> = (...args: TArgs) => Promise<TResult>;
528
539
  declare function cloudflareQueue<TArgs extends unknown[] = unknown[], TResult = unknown>(options: WithRetryCounterOptions): (target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<AsyncMethod<TArgs, TResult>>) => void;
529
540
 
530
- export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, idempotency, ip, isInternalError, jwt, logger, paginationQuerySchema, paginationSchema, service, signature, useFetch, useResult, useResultSync, uuidv4 };
541
+ export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, idempotency, ip, isInternalError, jwt, logger, paginationQuerySchema, paginationSchema, service, signPayload, signature, useFetch, useResult, useResultSync, uuidv4, verifyPayloadSignature };
531
542
  export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, AuthUser, BankAccountMetadata, BaseEvent, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, UserRole, UserVariables, ValidatedInput };
package/dist/index.d.ts CHANGED
@@ -438,6 +438,17 @@ interface UseFetchOptions extends RequestInit {
438
438
  }
439
439
  declare function useFetch<T = unknown>(url: string, { parseAs, ...options }?: UseFetchOptions): Promise<Result<T>>;
440
440
 
441
+ declare const signPayload: ({ payload, privateKey, }: {
442
+ payload: string;
443
+ privateKey: string;
444
+ }) => Promise<string>;
445
+ declare const verifyPayloadSignature: ({ signature, data, publicKey, algorithm, }: {
446
+ signature: string;
447
+ data: string;
448
+ publicKey: string;
449
+ algorithm?: "RSA" | "EC" | "HMAC";
450
+ }) => Promise<boolean>;
451
+
441
452
  declare const calculateExponentialBackoff: (attempts: number, baseDelaySeconds: number) => number;
442
453
 
443
454
  declare const RPCResponse: {
@@ -527,5 +538,5 @@ interface WithRetryCounterOptions {
527
538
  type AsyncMethod<TArgs extends unknown[] = unknown[], TResult = unknown> = (...args: TArgs) => Promise<TResult>;
528
539
  declare function cloudflareQueue<TArgs extends unknown[] = unknown[], TResult = unknown>(options: WithRetryCounterOptions): (target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<AsyncMethod<TArgs, TResult>>) => void;
529
540
 
530
- export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, idempotency, ip, isInternalError, jwt, logger, paginationQuerySchema, paginationSchema, service, signature, useFetch, useResult, useResultSync, uuidv4 };
541
+ export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, idempotency, ip, isInternalError, jwt, logger, paginationQuerySchema, paginationSchema, service, signPayload, signature, useFetch, useResult, useResultSync, uuidv4, verifyPayloadSignature };
531
542
  export type { ActionExecution, ActionHandlerOptions, AuditLogWriter, AuthUser, BankAccountMetadata, BaseEvent, Command, CommandLogPayload, DevelitWorkerMethods, Environment, GatewayResponse, IRPCResponse, IdempotencyVariables, IncludeRelation, InferResultType, InternalError, InternalErrorResponseStatus, Project, UserRole, UserVariables, ValidatedInput };
package/dist/index.mjs CHANGED
@@ -473,6 +473,37 @@ const logResponse = (log) => {
473
473
  console.log(`RESPONSE | An outgoing response has been recorded.`, log);
474
474
  };
475
475
 
476
+ const signPayload = async ({
477
+ payload,
478
+ privateKey
479
+ }) => {
480
+ const binaryPrivateKey = Uint8Array.from(
481
+ atob(privateKey),
482
+ (c) => c.charCodeAt(0)
483
+ );
484
+ const importedPrivateKey = await crypto.subtle.importKey(
485
+ "pkcs8",
486
+ binaryPrivateKey,
487
+ {
488
+ name: "RSASSA-PKCS1-v1_5",
489
+ hash: "SHA-256"
490
+ },
491
+ false,
492
+ ["sign"]
493
+ );
494
+ const encodedPayload = new TextEncoder().encode(payload);
495
+ const signature = await crypto.subtle.sign(
496
+ {
497
+ name: "RSASSA-PKCS1-v1_5"
498
+ },
499
+ importedPrivateKey,
500
+ encodedPayload
501
+ );
502
+ const base64Signature = btoa(
503
+ String.fromCharCode(...new Uint8Array(signature))
504
+ );
505
+ return base64Signature;
506
+ };
476
507
  const algParams = {
477
508
  RSA: {
478
509
  name: "RSASSA-PKCS1-v1_5",
@@ -487,7 +518,7 @@ const algParams = {
487
518
  hash: { name: "SHA-256" }
488
519
  }
489
520
  };
490
- const verify = async ({
521
+ const verifyPayloadSignature = async ({
491
522
  signature,
492
523
  data,
493
524
  publicKey,
@@ -583,36 +614,35 @@ const jwt = () => {
583
614
 
584
615
  const ip = () => {
585
616
  return createMiddleware(async (context, next) => {
586
- if (["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
587
- await next();
588
- }
589
- const requestIp = context.req.header("cf-connecting-ip") || context.req.header("x-forwarded-for");
590
- if (!requestIp) {
591
- throw new HTTPException(401, {
592
- message: "Failed to retrieve request IP address."
593
- });
594
- }
595
- const user = context.get("user");
596
- if (!user.organizationId) {
597
- throw new HTTPException(401, {
598
- message: "Failed to retrieve request organization ID."
599
- });
600
- }
601
- const organizationService = context.env.ORGANIZATION_SERVICE;
602
- const { data: organization, error } = await organizationService.getOrganization({
603
- organizationId: user.organizationId
604
- });
605
- if (!organization || error) {
606
- throw new HTTPException(404, {
607
- message: "Failed to retrieve organization."
617
+ if (!["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
618
+ const requestIp = context.req.header("cf-connecting-ip") || context.req.header("x-forwarded-for");
619
+ if (!requestIp) {
620
+ throw new HTTPException(401, {
621
+ message: "Failed to retrieve request IP address."
622
+ });
623
+ }
624
+ const user = context.get("user");
625
+ if (!user.organizationId) {
626
+ throw new HTTPException(401, {
627
+ message: "Failed to retrieve request organization ID."
628
+ });
629
+ }
630
+ const organizationService = context.env.ORGANIZATION_SERVICE;
631
+ const { data: organization, error } = await organizationService.getOrganization({
632
+ organizationId: user.organizationId
608
633
  });
609
- }
610
- if (organization.ipAuthorization) {
611
- if (!organization.authorizedIps.map((ip2) => ip2.ip).includes(requestIp)) {
634
+ if (!organization || error) {
612
635
  throw new HTTPException(404, {
613
- message: "Forbidden"
636
+ message: "Failed to retrieve organization."
614
637
  });
615
638
  }
639
+ if (organization.ipAuthorization) {
640
+ if (!organization.authorizedIps.map((ip2) => ip2.ip).includes(requestIp)) {
641
+ throw new HTTPException(404, {
642
+ message: "Forbidden"
643
+ });
644
+ }
645
+ }
616
646
  }
617
647
  await next();
618
648
  });
@@ -655,54 +685,53 @@ const logger = () => {
655
685
 
656
686
  const signature = () => {
657
687
  return createMiddleware(async (context, next) => {
658
- if (["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
659
- await next();
660
- }
661
- const signatureHeader = context.req.header("X-Signature");
662
- if (!signatureHeader) {
663
- throw new HTTPException(401, {
664
- message: `The 'X-Signature' header must exist and must have a value.`
665
- });
666
- }
667
- const signatureKeyHeader = context.req.header("X-Signature-Key");
668
- if (!signatureKeyHeader) {
669
- throw new HTTPException(401, {
670
- message: `The 'X-Signature-Key' header must exist and must have a value.`
671
- });
672
- }
673
- const payload = JSON.stringify(await context.req.json().catch(() => null));
674
- const user = context.get("user");
675
- if (!user.organizationId) {
676
- throw new HTTPException(401, {
677
- message: "Failed to retrieve request organization ID."
678
- });
679
- }
680
- const organizationService = context.env.ORGANIZATION_SERVICE;
681
- const { data: organization, error } = await organizationService.getOrganization({
682
- organizationId: user.organizationId
683
- });
684
- if (!organization || error) {
685
- throw new HTTPException(404, {
686
- message: "Failed to retrieve organization."
687
- });
688
- }
689
- const signatureKey = organization.signatureKeys.filter(
690
- (signatureKey2) => signatureKey2.name === signatureKeyHeader
691
- )[0];
692
- if (!signatureKey) {
693
- throw new HTTPException(404, {
694
- message: "Signature key not found."
688
+ if (!["localhost", "dev"].includes(context.env.ENVIRONMENT)) {
689
+ const signatureHeader = context.req.header("X-Signature");
690
+ if (!signatureHeader) {
691
+ throw new HTTPException(401, {
692
+ message: `The 'X-Signature' header must exist and must have a value.`
693
+ });
694
+ }
695
+ const signatureKeyHeader = context.req.header("X-Signature-Key");
696
+ if (!signatureKeyHeader) {
697
+ throw new HTTPException(401, {
698
+ message: `The 'X-Signature-Key' header must exist and must have a value.`
699
+ });
700
+ }
701
+ const payload = JSON.stringify(await context.req.json().catch(() => null));
702
+ const user = context.get("user");
703
+ if (!user.organizationId) {
704
+ throw new HTTPException(401, {
705
+ message: "Failed to retrieve request organization ID."
706
+ });
707
+ }
708
+ const organizationService = context.env.ORGANIZATION_SERVICE;
709
+ const { data: organization, error } = await organizationService.getOrganization({
710
+ organizationId: user.organizationId
695
711
  });
696
- }
697
- const isVerified = await verify({
698
- signature: signatureHeader,
699
- publicKey: signatureKey.publicKey,
700
- data: payload
701
- });
702
- if (!isVerified) {
703
- throw new HTTPException(401, {
704
- message: "Invalid signature key or signature."
712
+ if (!organization || error) {
713
+ throw new HTTPException(404, {
714
+ message: "Failed to retrieve organization."
715
+ });
716
+ }
717
+ const signatureKey = organization.signatureKeys.filter(
718
+ (signatureKey2) => signatureKey2.name === signatureKeyHeader
719
+ )[0];
720
+ if (!signatureKey) {
721
+ throw new HTTPException(404, {
722
+ message: "Signature key not found."
723
+ });
724
+ }
725
+ const isVerified = await verifyPayloadSignature({
726
+ signature: signatureHeader,
727
+ publicKey: signatureKey.publicKey,
728
+ data: payload
705
729
  });
730
+ if (!isVerified) {
731
+ throw new HTTPException(401, {
732
+ message: "Invalid signature key or signature."
733
+ });
734
+ }
706
735
  }
707
736
  await next();
708
737
  });
@@ -950,4 +979,4 @@ function develitWorker(Worker) {
950
979
  return DevelitWorker;
951
980
  }
952
981
 
953
- export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, idempotency, ip, isInternalError, jwt, logger, paginationQuerySchema, paginationSchema, service, signature, useFetch, useResult, useResultSync, uuidv4 };
982
+ export { DatabaseTransaction, ENVIRONMENT, RPCResponse, USER_ROLES, action, bankAccount, bankAccountMetadataSchema, base, bicSchema, calculateExponentialBackoff, cloudflareQueue, composeWranglerBase, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getSecret, handleAction, handleActionResponse, ibanSchema, idempotency, ip, isInternalError, jwt, logger, paginationQuerySchema, paginationSchema, service, signPayload, signature, useFetch, useResult, useResultSync, uuidv4, verifyPayloadSignature };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@develit-io/backend-sdk",
3
- "version": "5.40.1",
3
+ "version": "5.42.0",
4
4
  "description": "Develit Backend SDK",
5
5
  "author": "Develit.io",
6
6
  "license": "ISC",