@denodeio/seshat 0.0.32 → 0.0.34

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.
@@ -1,36 +1,4 @@
1
- /// <reference types="node" />
2
- type JwsSignature = {
3
- protected: string;
4
- header: {
5
- kid: string;
6
- };
7
- signature: string;
8
- };
9
- type JwsPayload = {
10
- payload: string;
11
- signatures: JwsSignature[];
12
- };
13
- type Keychain = {
14
- algorithm: string;
15
- value: Buffer;
16
- };
17
- type JwtPayload<T> = {
18
- iss: string;
19
- exp: number;
20
- jti: string;
21
- event: {
22
- name: string;
23
- record: T;
24
- };
25
- iat: number;
26
- };
1
+ export * from "./middleware";
27
2
  export * from "./signer";
28
- type OptionsInput = {
29
- fieldName?: string;
30
- barongJwtPublicKey?: string;
31
- jwtPublicKey?: string;
32
- issuer?: string;
33
- };
34
- export declare const sessionVerifier: (options: OptionsInput) => (req: any, res: any, next: any) => void;
35
- export declare const managementSigner: (options: any) => (req: any, res: any, next: any) => void;
36
- export declare const validateJws: <T>(key: Keychain, input: JwsPayload) => JwtPayload<T> | undefined;
3
+ export * from "./validate";
4
+ export * from "./types";
@@ -0,0 +1,9 @@
1
+ export declare const managementSigner: (options: any) => (req: any, res: any, next: any) => void;
2
+ type OptionsInput = {
3
+ fieldName?: string;
4
+ barongJwtPublicKey?: string;
5
+ jwtPublicKey?: string;
6
+ issuer?: string;
7
+ };
8
+ export declare const sessionVerifier: (options: OptionsInput) => (req: any, res: any, next: any) => void;
9
+ export {};
@@ -0,0 +1,6 @@
1
+ import { PublicKey, Secret } from "jsonwebtoken";
2
+ export type Key = {
3
+ algorithm: string;
4
+ value: Secret | PublicKey;
5
+ };
6
+ export type Keychain = Map<string, Key>;
@@ -0,0 +1,7 @@
1
+ type ProtectedHeader = {
2
+ alg: string;
3
+ typ: string;
4
+ };
5
+ export declare const base64Decode: (base64: string) => string;
6
+ export declare const parseProtectedHeader: (protectedHeader: string) => ProtectedHeader;
7
+ export {};
@@ -0,0 +1,28 @@
1
+ import { Key, Keychain } from "./types";
2
+ type JwsSignature = {
3
+ protected: string;
4
+ header: {
5
+ kid: string;
6
+ };
7
+ signature: string;
8
+ };
9
+ type JwsPayload = {
10
+ payload: string;
11
+ signatures: JwsSignature[];
12
+ };
13
+ type JwtPayload<T> = {
14
+ iss: string;
15
+ exp: number;
16
+ jti: string;
17
+ event: {
18
+ name: string;
19
+ record: T;
20
+ };
21
+ iat: number;
22
+ };
23
+ export declare const validateJws: <T>(key: Key, input: JwsPayload) => JwtPayload<T> | undefined;
24
+ export declare const validateJwsMultisig: <T>(keychain: Keychain, input: JwsPayload) => {
25
+ verified: string[];
26
+ unverified: string[];
27
+ };
28
+ export {};
@@ -1,4 +1,14 @@
1
- /// <reference types="node" />
1
+ import { Secret, PublicKey } from 'jsonwebtoken';
2
+
3
+ declare const managementSigner: (options: any) => (req: any, res: any, next: any) => void;
4
+ type OptionsInput = {
5
+ fieldName?: string;
6
+ barongJwtPublicKey?: string;
7
+ jwtPublicKey?: string;
8
+ issuer?: string;
9
+ };
10
+ declare const sessionVerifier: (options: OptionsInput) => (req: any, res: any, next: any) => void;
11
+
2
12
  type SignJwsResponse = {
3
13
  payload: string;
4
14
  signatures: {
@@ -13,6 +23,12 @@ declare function signJws(payload: string, options: any): SignJwsResponse;
13
23
  declare function signPayload(payload: any, options: any): string;
14
24
  declare function signData(payload: object, options: any): SignJwsResponse;
15
25
 
26
+ type Key = {
27
+ algorithm: string;
28
+ value: Secret | PublicKey;
29
+ };
30
+ type Keychain = Map<string, Key>;
31
+
16
32
  type JwsSignature = {
17
33
  protected: string;
18
34
  header: {
@@ -24,10 +40,6 @@ type JwsPayload = {
24
40
  payload: string;
25
41
  signatures: JwsSignature[];
26
42
  };
27
- type Keychain = {
28
- algorithm: string;
29
- value: Buffer;
30
- };
31
43
  type JwtPayload<T> = {
32
44
  iss: string;
33
45
  exp: number;
@@ -38,15 +50,10 @@ type JwtPayload<T> = {
38
50
  };
39
51
  iat: number;
40
52
  };
41
-
42
- type OptionsInput = {
43
- fieldName?: string;
44
- barongJwtPublicKey?: string;
45
- jwtPublicKey?: string;
46
- issuer?: string;
53
+ declare const validateJws: <T>(key: Key, input: JwsPayload) => JwtPayload<T> | undefined;
54
+ declare const validateJwsMultisig: <T>(keychain: Keychain, input: JwsPayload) => {
55
+ verified: string[];
56
+ unverified: string[];
47
57
  };
48
- declare const sessionVerifier: (options: OptionsInput) => (req: any, res: any, next: any) => void;
49
- declare const managementSigner: (options: any) => (req: any, res: any, next: any) => void;
50
- declare const validateJws: <T>(key: Keychain, input: JwsPayload) => JwtPayload<T> | undefined;
51
58
 
52
- export { managementSigner, sessionVerifier, signData, signJws, signPayload, validateJws };
59
+ export { type Key, type Keychain, managementSigner, sessionVerifier, signData, signJws, signPayload, validateJws, validateJwsMultisig };
@@ -6507,6 +6507,33 @@ function signData(payload, options) {
6507
6507
  return signJws(signedPayload, options);
6508
6508
  }
6509
6509
 
6510
+ const managementSigner = function (options) {
6511
+ if (!options.privateKey)
6512
+ throw new Error("Application's private key should be set");
6513
+ const middleware = function (req, res, next) {
6514
+ if (!req.management.payload)
6515
+ console.error("No payload to be signed");
6516
+ const payload = req.management.payload;
6517
+ let signedPayload;
6518
+ try {
6519
+ signedPayload = signPayload(payload, options);
6520
+ }
6521
+ catch (error) {
6522
+ res.status(403);
6523
+ res.send(`Unable to sign payload: ${error}`);
6524
+ return;
6525
+ }
6526
+ try {
6527
+ req.body = signJws(signedPayload, options);
6528
+ }
6529
+ catch (error) {
6530
+ res.status(403);
6531
+ res.send(`Unable to correctly format signed payload: ${error}`);
6532
+ }
6533
+ next();
6534
+ };
6535
+ return middleware;
6536
+ };
6510
6537
  const sessionVerifier = function (options) {
6511
6538
  const { fieldName = "session", ...actualOptions } = options;
6512
6539
  if (!options || (!options.barongJwtPublicKey && !options.jwtPublicKey)) {
@@ -6528,6 +6555,9 @@ const sessionVerifier = function (options) {
6528
6555
  res.send("Signature verification raised: Authorization header is missing or malformed");
6529
6556
  return;
6530
6557
  }
6558
+ if (!jwtPublicKey) {
6559
+ throw new Error("JWT Public key should be set");
6560
+ }
6531
6561
  try {
6532
6562
  req[fieldName] = jwt.verify(authHeader, jwtPublicKey, verificationOptions);
6533
6563
  }
@@ -6540,39 +6570,14 @@ const sessionVerifier = function (options) {
6540
6570
  };
6541
6571
  return middleware;
6542
6572
  };
6543
- const managementSigner = function (options) {
6544
- if (!options.privateKey)
6545
- throw new Error("Application's private key should be set");
6546
- const middleware = function (req, res, next) {
6547
- if (!req.management.payload)
6548
- console.error("No payload to be signed");
6549
- const payload = req.management.payload;
6550
- let signedPayload;
6551
- try {
6552
- signedPayload = signPayload(payload, options);
6553
- }
6554
- catch (error) {
6555
- res.status(403);
6556
- res.send(`Unable to sign payload: ${error}`);
6557
- return;
6558
- }
6559
- try {
6560
- req.body = signJws(signedPayload, options);
6561
- }
6562
- catch (error) {
6563
- res.status(403);
6564
- res.send(`Unable to correctly format signed payload: ${error}`);
6565
- }
6566
- next();
6567
- };
6568
- return middleware;
6569
- };
6573
+
6570
6574
  const base64Decode = (base64) => {
6571
6575
  return Buffer.from(base64, "base64").toString("utf8");
6572
6576
  };
6573
6577
  const parseProtectedHeader = (protectedHeader) => {
6574
6578
  return JSON.parse(base64Decode(protectedHeader));
6575
6579
  };
6580
+
6576
6581
  const validateJws = (key, input) => {
6577
6582
  for (const signature of input.signatures) {
6578
6583
  const decodedProtectedHeader = parseProtectedHeader(signature.protected);
@@ -6582,18 +6587,63 @@ const validateJws = (key, input) => {
6582
6587
  if (key.algorithm !== decodedProtectedHeader.alg) {
6583
6588
  throw new Error("Algorithm mismatch");
6584
6589
  }
6585
- try {
6586
- const verified = jwt.verify(`${signature.protected}.${input.payload}.${signature.signature}`, key.value,
6587
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
6588
- { algorithms: [key.algorithm] });
6589
- return verified;
6590
+ const verified = jwt.verify(`${signature.protected}.${input.payload}.${signature.signature}`, key.value,
6591
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6592
+ { algorithms: [key.algorithm] });
6593
+ return verified;
6594
+ }
6595
+ };
6596
+ /*
6597
+ * Verifies JWT.
6598
+ *
6599
+ * @param jwt [Hash]
6600
+ * The JWT in the format as defined in RFC 7515.
6601
+ * Example:
6602
+ * { "payload" => "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
6603
+ * "signatures" => [
6604
+ * { "protected" => "eyJhbGciOiJSUzI1NiJ9",
6605
+ * "header" => { "kid" => "2010-12-29" },
6606
+ * "signature" => "cC4hiUPoj9Eetdgtv3hF80EGrhuB__dzERat0XF9g2VtQgr9PJbu3XOiZj5RZmh7AAuHIm4Bh-0Qc_lF5YKt_O8W2Fp5jujGbds9uJdbF9CUAr7t1dnZcAcQjbKBYNX4BAynRFdiuB--f_nZLgrnbyTyWzO75vRK5h6xBArLIARNPvkSjtQBMHlb1L07Qe7K0GarZRmB_eSN9383LcOLn6_dO--xi12jzDwusC-eOkHWEsqtFZESc6BfI7noOPqvhJ1phCnvWh6IeYI2w9QOYEUipUTI8np6LbgGY9Fs98rqVt5AXLIhWkWywlVmtVrBp0igcN_IoypGlUPQGe77Rw"
6607
+ * },
6608
+ * { "protected" => "eyJhbGciOiJFUzI1NiJ9",
6609
+ * "header" => { "kid" => "e9bc097a-ce51-4036-9562-d2ade882db0d" },
6610
+ * "signature" => "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q"
6611
+ * }
6612
+ * ]
6613
+ * }
6614
+ * @param public_keychain [Hash]
6615
+ * The hash which consists of pairs: key ID => public key.
6616
+ * The key may be presented as string in PEM format or as instance of {OpenSSL::PKey::PKey}.
6617
+ * The implementation only verifies signatures for which public key exists in keychain.
6618
+ * @param options [Hash]
6619
+ * The rules for verifying JWT. The variable «algorithms» is always overwritten by the value from JWS header.
6620
+ * @return [Hash]
6621
+ * The returning value contains payload, list of verified, and unverified signatures (key ID).
6622
+ * Example:
6623
+ * { payload: { sub: "session", profile: { email: "username@mailbox.example" },
6624
+ * verified: [:"backend-1.mycompany.example", :"backend-3.mycompany.example"],
6625
+ * unverified: [:"backend-2.mycompany.example"] }
6626
+ * }
6627
+ * @raise [JWT::DecodeError]
6628
+ */
6629
+ const validateJwsMultisig = (keychain, input) => {
6630
+ const verified = [];
6631
+ const unverified = [];
6632
+ for (const signature of input.signatures) {
6633
+ const key = keychain.get(signature.header.kid);
6634
+ if (key) {
6635
+ validateJws(key, input);
6636
+ verified.push(signature.header.kid);
6590
6637
  }
6591
- catch (error) {
6592
- console.error(error);
6593
- return undefined;
6638
+ else {
6639
+ unverified.push(signature.header.kid);
6594
6640
  }
6595
6641
  }
6642
+ return {
6643
+ verified,
6644
+ unverified
6645
+ };
6596
6646
  };
6597
6647
 
6598
- export { managementSigner, sessionVerifier, signData, signJws, signPayload, validateJws };
6648
+ export { managementSigner, sessionVerifier, signData, signJws, signPayload, validateJws, validateJwsMultisig };
6599
6649
  //# sourceMappingURL=index.js.map