@opengovsg/formsg-sdk 0.10.0 → 0.12.0-alpha.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/errors.js CHANGED
@@ -3,16 +3,19 @@ var __extends = (this && this.__extends) || (function () {
3
3
  var extendStatics = function (d, b) {
4
4
  extendStatics = Object.setPrototypeOf ||
5
5
  ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
7
  return extendStatics(d, b);
8
8
  };
9
9
  return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
10
12
  extendStatics(d, b);
11
13
  function __() { this.constructor = d; }
12
14
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13
15
  };
14
16
  })();
15
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.AttachmentDecryptionError = exports.WebhookAuthenticateError = exports.MissingPublicKeyError = exports.MissingSecretKeyError = void 0;
16
19
  var MissingSecretKeyError = /** @class */ (function (_super) {
17
20
  __extends(MissingSecretKeyError, _super);
18
21
  function MissingSecretKeyError(message) {
package/dist/index.d.ts CHANGED
@@ -1,12 +1,8 @@
1
1
  import Crypto from './crypto';
2
+ import CryptoV3 from './crypto-v3';
2
3
  import { PackageInitParams } from './types';
3
4
  import Verification from './verification';
4
5
  import Webhooks from './webhooks';
5
- declare const _default: (config?: PackageInitParams) => {
6
- webhooks: Webhooks;
7
- crypto: Crypto;
8
- verification: Verification;
9
- };
10
6
  /**
11
7
  * Entrypoint into the FormSG SDK
12
8
  *
@@ -15,4 +11,10 @@ declare const _default: (config?: PackageInitParams) => {
15
11
  * @param {string?} [config.webhookSecretKey] Optional. base64 secret key for signing webhooks. If provided, enables generating signature and headers to authenticate webhook data.
16
12
  * @param {VerificationOptions?} [config.verificationOptions] Optional. If provided, enables the usage of the verification module.
17
13
  */
14
+ declare const _default: (config?: PackageInitParams) => {
15
+ webhooks: Webhooks;
16
+ crypto: Crypto;
17
+ cryptoV3: CryptoV3;
18
+ verification: Verification;
19
+ };
18
20
  export = _default;
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  var publicKey_1 = require("./util/publicKey");
6
6
  var crypto_1 = __importDefault(require("./crypto"));
7
+ var crypto_v3_1 = __importDefault(require("./crypto-v3"));
7
8
  var verification_1 = __importDefault(require("./verification"));
8
9
  var webhooks_1 = __importDefault(require("./webhooks"));
9
10
  module.exports = function (config) {
@@ -13,17 +14,18 @@ module.exports = function (config) {
13
14
  * Public key is used for decrypting signed verified content in the `crypto` module, and
14
15
  * also for verifying webhook signatures' authenticity in the `wehbooks` module.
15
16
  */
16
- var signingPublicKey = publicKey_1.getSigningPublicKey(mode || 'production');
17
+ var signingPublicKey = (0, publicKey_1.getSigningPublicKey)(mode || 'production');
17
18
  /**
18
19
  * Public key is used for verifying verified field signatures' authenticity in the `verification` module.
19
20
  */
20
- var verificationPublicKey = publicKey_1.getVerificationPublicKey(mode || 'production');
21
+ var verificationPublicKey = (0, publicKey_1.getVerificationPublicKey)(mode || 'production');
21
22
  return {
22
23
  webhooks: new webhooks_1.default({
23
24
  publicKey: signingPublicKey,
24
25
  secretKey: webhookSecretKey,
25
26
  }),
26
27
  crypto: new crypto_1.default({ signingPublicKey: signingPublicKey }),
28
+ cryptoV3: new crypto_v3_1.default(),
27
29
  verification: new verification_1.default({
28
30
  publicKey: verificationPublicKey,
29
31
  secretKey: verificationOptions === null || verificationOptions === void 0 ? void 0 : verificationOptions.secretKey,
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SIGNING_KEYS = void 0;
3
4
  // keys generated using nacl.sign.keyPair() from tweetnacl
4
5
  exports.SIGNING_KEYS = {
5
6
  staging: {
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VERIFICATION_KEYS = void 0;
3
4
  // keys generated using nacl.sign.keyPair() from tweetnacl
4
5
  exports.VERIFICATION_KEYS = {
5
6
  staging: {
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare type PackageInitParams = {
1
+ export type PackageInitParams = {
2
2
  /** base64 secret key for signing webhooks. If provided, enables generating signature and headers to authenticate webhook data. */
3
3
  webhookSecretKey?: string;
4
4
  /** If provided, enables the usage of the verification module. */
@@ -6,8 +6,8 @@ export declare type PackageInitParams = {
6
6
  /** Initializes public key used for verifying and decrypting in this package. If not given, will default to "production". */
7
7
  mode?: PackageMode;
8
8
  };
9
- export declare type FieldType = 'section' | 'radiobutton' | 'dropdown' | 'checkbox' | 'nric' | 'email' | 'table' | 'number' | 'rating' | 'yes_no' | 'decimal' | 'textfield' | 'textarea' | 'attachment' | 'date' | 'mobile' | 'homeno';
10
- export declare type FormField = {
9
+ export type FieldType = 'section' | 'radiobutton' | 'dropdown' | 'checkbox' | 'nric' | 'email' | 'table' | 'number' | 'rating' | 'yes_no' | 'decimal' | 'textfield' | 'textarea' | 'attachment' | 'date' | 'mobile' | 'homeno' | 'statement' | 'image' | 'country_region' | 'uen' | 'children';
10
+ export type FormField = {
11
11
  _id: string;
12
12
  question: string;
13
13
  fieldType: FieldType;
@@ -20,61 +20,80 @@ export declare type FormField = {
20
20
  answer?: never;
21
21
  answerArray: string[] | string[][];
22
22
  });
23
- export declare type EncryptedContent = string;
24
- export declare type EncryptedAttachmentRecords = Record<string, string>;
23
+ export type FormFieldsV3 = Record<string, {
24
+ fieldType: FieldType;
25
+ answer: any;
26
+ }>;
27
+ export type EncryptedContent = string;
28
+ export type EncryptedContentV3 = {
29
+ submissionPublicKey: string;
30
+ submissionSecretKey: string;
31
+ encryptedContent: EncryptedContent;
32
+ encryptedSubmissionSecretKey: EncryptedContent;
33
+ };
34
+ export type EncryptedAttachmentRecords = Record<string, string>;
25
35
  export interface DecryptParams {
26
36
  encryptedContent: EncryptedContent;
27
37
  version: number;
28
38
  verifiedContent?: EncryptedContent;
29
39
  attachmentDownloadUrls?: EncryptedAttachmentRecords;
30
40
  }
31
- export declare type DecryptedContent = {
41
+ export interface DecryptParamsV3 {
42
+ encryptedContent: EncryptedContent;
43
+ encryptedSubmissionSecretKey: EncryptedContent;
44
+ version: number;
45
+ }
46
+ export type DecryptedContent = {
32
47
  responses: FormField[];
33
48
  verified?: Record<string, any>;
34
49
  };
35
- export declare type DecryptedFile = {
50
+ export type DecryptedContentV3 = {
51
+ submissionSecretKey: string;
52
+ responses: FormFieldsV3;
53
+ };
54
+ export type DecryptedFile = {
36
55
  filename: string;
37
56
  content: Uint8Array;
38
57
  };
39
- export declare type DecryptedAttachments = Record<string, DecryptedFile>;
40
- export declare type DecryptedContentAndAttachments = {
58
+ export type DecryptedAttachments = Record<string, DecryptedFile>;
59
+ export type DecryptedContentAndAttachments = {
41
60
  content: DecryptedContent;
42
61
  attachments: DecryptedAttachments;
43
62
  };
44
- export declare type EncryptedFileContent = {
63
+ export type EncryptedFileContent = {
45
64
  submissionPublicKey: string;
46
65
  nonce: string;
47
66
  binary: Uint8Array;
48
67
  };
49
- export declare type EncryptedAttachmentContent = {
68
+ export type EncryptedAttachmentContent = {
50
69
  encryptedFile: {
51
70
  submissionPublicKey: string;
52
71
  nonce: string;
53
72
  binary: string;
54
73
  };
55
74
  };
56
- export declare type Keypair = {
75
+ export type Keypair = {
57
76
  publicKey: string;
58
77
  secretKey: string;
59
78
  };
60
- export declare type PackageMode = 'staging' | 'production' | 'development' | 'test';
61
- export declare type VerificationOptions = {
79
+ export type PackageMode = 'staging' | 'production' | 'development' | 'test';
80
+ export type VerificationOptions = {
62
81
  publicKey?: string;
63
82
  secretKey?: string;
64
83
  transactionExpiry?: number;
65
84
  };
66
- export declare type VerifiedAnswer = {
85
+ export type VerifiedAnswer = {
67
86
  fieldId: string;
68
87
  answer: string;
69
88
  };
70
- export declare type VerificationSignatureOptions = VerifiedAnswer & {
89
+ export type VerificationSignatureOptions = VerifiedAnswer & {
71
90
  transactionId: string;
72
91
  formId: string;
73
92
  };
74
- export declare type VerificationBasestringOptions = VerificationSignatureOptions & {
93
+ export type VerificationBasestringOptions = VerificationSignatureOptions & {
75
94
  time: number;
76
95
  };
77
- export declare type VerificationAuthenticateOptions = VerifiedAnswer & {
96
+ export type VerificationAuthenticateOptions = VerifiedAnswer & {
78
97
  signatureString: string;
79
98
  submissionCreatedAt: number;
80
99
  };
@@ -1,4 +1,4 @@
1
- import { Keypair, EncryptedAttachmentContent, EncryptedFileContent } from '../types';
1
+ import { EncryptedAttachmentContent, EncryptedContent, EncryptedFileContent, Keypair } from '../types';
2
2
  /**
3
3
  * Helper method to generate a new keypair for encryption.
4
4
  * @returns The generated keypair.
@@ -11,14 +11,14 @@ export declare const generateKeypair: () => Keypair;
11
11
  * @returns The encrypted basestring
12
12
  * @throws error if any of the encrypt methods fail
13
13
  */
14
- export declare const encryptMessage: (msg: Uint8Array, theirPublicKey: string) => string;
14
+ export declare const encryptMessage: (msg: Uint8Array, theirPublicKey: string) => EncryptedContent;
15
15
  /**
16
16
  * Helper method to decrypt an encrypted submission.
17
17
  * @param formPrivateKey base64
18
18
  * @param encryptedContent encrypted string encoded in base64
19
19
  * @return The decrypted content, or null if decryption failed.
20
20
  */
21
- export declare const decryptContent: (formPrivateKey: string, encryptedContent: string) => Uint8Array | null;
21
+ export declare const decryptContent: (formPrivateKey: string, encryptedContent: EncryptedContent) => Uint8Array | null;
22
22
  /**
23
23
  * Helper method to verify a signed message.
24
24
  * @param msg the message to verify
@@ -3,19 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.convertEncryptedAttachmentToFileContent = exports.areAttachmentFieldIdsValid = exports.verifySignedMessage = exports.decryptContent = exports.encryptMessage = exports.generateKeypair = void 0;
6
7
  var tweetnacl_1 = __importDefault(require("tweetnacl"));
7
8
  var tweetnacl_util_1 = require("tweetnacl-util");
8
9
  /**
9
10
  * Helper method to generate a new keypair for encryption.
10
11
  * @returns The generated keypair.
11
12
  */
12
- exports.generateKeypair = function () {
13
+ var generateKeypair = function () {
13
14
  var kp = tweetnacl_1.default.box.keyPair();
14
15
  return {
15
- publicKey: tweetnacl_util_1.encodeBase64(kp.publicKey),
16
- secretKey: tweetnacl_util_1.encodeBase64(kp.secretKey),
16
+ publicKey: (0, tweetnacl_util_1.encodeBase64)(kp.publicKey),
17
+ secretKey: (0, tweetnacl_util_1.encodeBase64)(kp.secretKey),
17
18
  };
18
19
  };
20
+ exports.generateKeypair = generateKeypair;
19
21
  /**
20
22
  * Helper function to encrypt input with a unique keypair for each submission.
21
23
  * @param msg The message to encrypt
@@ -23,28 +25,30 @@ exports.generateKeypair = function () {
23
25
  * @returns The encrypted basestring
24
26
  * @throws error if any of the encrypt methods fail
25
27
  */
26
- exports.encryptMessage = function (msg, theirPublicKey) {
27
- var submissionKeypair = exports.generateKeypair();
28
+ var encryptMessage = function (msg, theirPublicKey) {
29
+ var submissionKeypair = (0, exports.generateKeypair)();
28
30
  var nonce = tweetnacl_1.default.randomBytes(24);
29
- var encrypted = tweetnacl_util_1.encodeBase64(tweetnacl_1.default.box(msg, nonce, tweetnacl_util_1.decodeBase64(theirPublicKey), tweetnacl_util_1.decodeBase64(submissionKeypair.secretKey)));
30
- return submissionKeypair.publicKey + ";" + tweetnacl_util_1.encodeBase64(nonce) + ":" + encrypted;
31
+ var encrypted = (0, tweetnacl_util_1.encodeBase64)(tweetnacl_1.default.box(msg, nonce, (0, tweetnacl_util_1.decodeBase64)(theirPublicKey), (0, tweetnacl_util_1.decodeBase64)(submissionKeypair.secretKey)));
32
+ return "".concat(submissionKeypair.publicKey, ";").concat((0, tweetnacl_util_1.encodeBase64)(nonce), ":").concat(encrypted);
31
33
  };
34
+ exports.encryptMessage = encryptMessage;
32
35
  /**
33
36
  * Helper method to decrypt an encrypted submission.
34
37
  * @param formPrivateKey base64
35
38
  * @param encryptedContent encrypted string encoded in base64
36
39
  * @return The decrypted content, or null if decryption failed.
37
40
  */
38
- exports.decryptContent = function (formPrivateKey, encryptedContent) {
41
+ var decryptContent = function (formPrivateKey, encryptedContent) {
39
42
  try {
40
43
  var _a = encryptedContent.split(';'), submissionPublicKey = _a[0], nonceEncrypted = _a[1];
41
44
  var _b = nonceEncrypted.split(':').map(tweetnacl_util_1.decodeBase64), nonce = _b[0], encrypted = _b[1];
42
- return tweetnacl_1.default.box.open(encrypted, nonce, tweetnacl_util_1.decodeBase64(submissionPublicKey), tweetnacl_util_1.decodeBase64(formPrivateKey));
45
+ return tweetnacl_1.default.box.open(encrypted, nonce, (0, tweetnacl_util_1.decodeBase64)(submissionPublicKey), (0, tweetnacl_util_1.decodeBase64)(formPrivateKey));
43
46
  }
44
47
  catch (err) {
45
48
  return null;
46
49
  }
47
50
  };
51
+ exports.decryptContent = decryptContent;
48
52
  /**
49
53
  * Helper method to verify a signed message.
50
54
  * @param msg the message to verify
@@ -52,28 +56,31 @@ exports.decryptContent = function (formPrivateKey, encryptedContent) {
52
56
  * @returns the signed message if successful, else an error will be thrown
53
57
  * @throws {Error} if the message cannot be verified
54
58
  */
55
- exports.verifySignedMessage = function (msg, publicKey) {
56
- var openedMessage = tweetnacl_1.default.sign.open(msg, tweetnacl_util_1.decodeBase64(publicKey));
59
+ var verifySignedMessage = function (msg, publicKey) {
60
+ var openedMessage = tweetnacl_1.default.sign.open(msg, (0, tweetnacl_util_1.decodeBase64)(publicKey));
57
61
  if (!openedMessage)
58
62
  throw new Error('Failed to open signed message with given public key');
59
- return JSON.parse(tweetnacl_util_1.encodeUTF8(openedMessage));
63
+ return JSON.parse((0, tweetnacl_util_1.encodeUTF8)(openedMessage));
60
64
  };
65
+ exports.verifySignedMessage = verifySignedMessage;
61
66
  /**
62
67
  * Helper method to check if all the field IDs given are within the filenames
63
68
  * @param fieldIds the list of fieldIds to check
64
69
  * @param filenames the filenames that should contain the fields
65
70
  * @returns boolean indicating whether the fields are valid
66
71
  */
67
- exports.areAttachmentFieldIdsValid = function (fieldIds, filenames) {
72
+ var areAttachmentFieldIdsValid = function (fieldIds, filenames) {
68
73
  return fieldIds.every(function (fieldId) { return filenames[fieldId]; });
69
74
  };
75
+ exports.areAttachmentFieldIdsValid = areAttachmentFieldIdsValid;
70
76
  /**
71
77
  * Converts an encrypted attachment to encrypted file content
72
78
  * @param encryptedAttachment The encrypted attachment
73
79
  * @returns EncryptedFileContent The encrypted file content
74
80
  */
75
- exports.convertEncryptedAttachmentToFileContent = function (encryptedAttachment) { return ({
81
+ var convertEncryptedAttachmentToFileContent = function (encryptedAttachment) { return ({
76
82
  submissionPublicKey: encryptedAttachment.encryptedFile.submissionPublicKey,
77
83
  nonce: encryptedAttachment.encryptedFile.nonce,
78
- binary: tweetnacl_util_1.decodeBase64(encryptedAttachment.encryptedFile.binary),
84
+ binary: (0, tweetnacl_util_1.decodeBase64)(encryptedAttachment.encryptedFile.binary),
79
85
  }); };
86
+ exports.convertEncryptedAttachmentToFileContent = convertEncryptedAttachmentToFileContent;
@@ -1,10 +1,10 @@
1
- export declare type HeaderSignature = {
1
+ export type HeaderSignature = {
2
2
  v1: string;
3
3
  t: number;
4
4
  s: string;
5
5
  f: string;
6
6
  };
7
- export declare type VerificationSignature = {
7
+ export type VerificationSignature = {
8
8
  v: string;
9
9
  t: number;
10
10
  s: string;
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseVerificationSignature = exports.parseSignatureHeader = void 0;
3
4
  /**
4
5
  * Helper function to retrieve keys-values in a signature.
5
6
  * @param signature The signature to convert to a keymap
@@ -20,18 +21,20 @@ var signatureToKeyMap = function (signature) {
20
21
  * @param header The X-FormSG-Signature header
21
22
  * @returns The signature header constituents
22
23
  */
23
- exports.parseSignatureHeader = function (header) {
24
+ var parseSignatureHeader = function (header) {
24
25
  var parsedSignature = signatureToKeyMap(header);
25
26
  parsedSignature.t = Number(parsedSignature.t);
26
27
  return parsedSignature;
27
28
  };
29
+ exports.parseSignatureHeader = parseSignatureHeader;
28
30
  /**
29
31
  * Parses the verification signature into its constituent
30
32
  * @param signature The verification signature
31
33
  * @returns The verification signature constituents
32
34
  */
33
- exports.parseVerificationSignature = function (signature) {
35
+ var parseVerificationSignature = function (signature) {
34
36
  var parsedSignature = signatureToKeyMap(signature);
35
37
  parsedSignature.t = Number(parsedSignature.t);
36
38
  return parsedSignature;
37
39
  };
40
+ exports.parseVerificationSignature = parseVerificationSignature;
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getVerificationPublicKey = exports.getSigningPublicKey = void 0;
6
7
  var signing_keys_1 = require("../resource/signing-keys");
7
8
  var verification_keys_1 = require("../resource/verification-keys");
8
9
  var stage_1 = __importDefault(require("./stage"));
@@ -1,12 +1,29 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __importStar = (this && this.__importStar) || function (mod) {
3
19
  if (mod && mod.__esModule) return mod;
4
20
  var result = {};
5
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
6
- result["default"] = mod;
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
7
23
  return result;
8
24
  };
9
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.verify = exports.sign = void 0;
10
27
  var tweetnacl = __importStar(require("tweetnacl"));
11
28
  var tweetnacl_util_1 = require("tweetnacl-util");
12
29
  /**
@@ -16,7 +33,7 @@ var tweetnacl_util_1 = require("tweetnacl-util");
16
33
  * @return base64 encoded signature
17
34
  */
18
35
  function sign(basestring, secretKey) {
19
- return tweetnacl_util_1.encodeBase64(tweetnacl.sign.detached(tweetnacl_util_1.decodeUTF8(basestring), tweetnacl_util_1.decodeBase64(secretKey)));
36
+ return (0, tweetnacl_util_1.encodeBase64)(tweetnacl.sign.detached((0, tweetnacl_util_1.decodeUTF8)(basestring), (0, tweetnacl_util_1.decodeBase64)(secretKey)));
20
37
  }
21
38
  exports.sign = sign;
22
39
  /**
@@ -27,6 +44,6 @@ exports.sign = sign;
27
44
  * @return True if verification checks out, false otherwise
28
45
  */
29
46
  function verify(message, signature, publicKey) {
30
- return tweetnacl.sign.detached.verify(tweetnacl_util_1.decodeUTF8(message), tweetnacl_util_1.decodeBase64(signature), tweetnacl_util_1.decodeBase64(publicKey));
47
+ return tweetnacl.sign.detached.verify((0, tweetnacl_util_1.decodeUTF8)(message), (0, tweetnacl_util_1.decodeBase64)(signature), (0, tweetnacl_util_1.decodeBase64)(publicKey));
31
48
  }
32
49
  exports.verify = verify;
@@ -1,3 +1,4 @@
1
- import { FormField } from '../types';
1
+ import { FormField, FormFieldsV3 } from '../types';
2
2
  declare function determineIsFormFields(tbd: any): tbd is FormField[];
3
- export { determineIsFormFields };
3
+ declare function determineIsFormFieldsV3(tbd: any): tbd is FormFieldsV3;
4
+ export { determineIsFormFields, determineIsFormFieldsV3 };
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.determineIsFormFieldsV3 = exports.determineIsFormFields = void 0;
3
4
  function determineIsFormFields(tbd) {
4
5
  if (!Array.isArray(tbd)) {
5
6
  return false;
@@ -21,3 +22,15 @@ function determineIsFormFields(tbd) {
21
22
  return filter.length === tbd.length;
22
23
  }
23
24
  exports.determineIsFormFields = determineIsFormFields;
25
+ // TODO(MRF): This is currently very rudimentary, we should look at making this more specific where required.
26
+ function determineIsFormFieldsV3(tbd) {
27
+ for (var _i = 0, _a = Object.keys(tbd); _i < _a.length; _i++) {
28
+ var id = _a[_i];
29
+ var value = tbd[id];
30
+ var hasCorrectShape = value.fieldType && value.answer !== undefined;
31
+ if (!hasCorrectShape)
32
+ return false;
33
+ }
34
+ return true;
35
+ }
36
+ exports.determineIsFormFieldsV3 = determineIsFormFieldsV3;
@@ -1,12 +1,29 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __importStar = (this && this.__importStar) || function (mod) {
3
19
  if (mod && mod.__esModule) return mod;
4
20
  var result = {};
5
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
6
- result["default"] = mod;
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
7
23
  return result;
8
24
  };
9
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.hasEpochExpired = exports.isSignatureHeaderValid = void 0;
10
27
  var url = __importStar(require("url"));
11
28
  var errors_1 = require("../errors");
12
29
  var signature_1 = require("./signature");
@@ -23,8 +40,8 @@ var isSignatureHeaderValid = function (uri, signatureHeader, publicKey) {
23
40
  if (!epoch || !signature || !submissionId || !formId) {
24
41
  throw new errors_1.WebhookAuthenticateError('X-FormSG-Signature header is invalid');
25
42
  }
26
- var baseString = url.parse(uri).href + "." + submissionId + "." + formId + "." + epoch;
27
- return signature_1.verify(baseString, signature, publicKey);
43
+ var baseString = "".concat(url.parse(uri).href, ".").concat(submissionId, ".").concat(formId, ".").concat(epoch);
44
+ return (0, signature_1.verify)(baseString, signature, publicKey);
28
45
  };
29
46
  exports.isSignatureHeaderValid = isSignatureHeaderValid;
30
47
  /**
@@ -33,27 +33,27 @@ var Verification = /** @class */ (function () {
33
33
  throw new errors_1.MissingPublicKeyError();
34
34
  }
35
35
  try {
36
- var _b = parser_1.parseVerificationSignature(signatureString), transactionId = _b.v, time = _b.t, formId = _b.f, signature = _b.s;
36
+ var _b = (0, parser_1.parseVerificationSignature)(signatureString), transactionId = _b.v, time = _b.t, formId = _b.f, signature = _b.s;
37
37
  if (!time) {
38
38
  throw new Error('Malformed signature string was passed into function');
39
39
  }
40
- if (utils_1.isSignatureTimeValid(time, submissionCreatedAt, _this.transactionExpiry)) {
41
- var data = utils_1.formatToBaseString({
40
+ if ((0, utils_1.isSignatureTimeValid)(time, submissionCreatedAt, _this.transactionExpiry)) {
41
+ var data = (0, utils_1.formatToBaseString)({
42
42
  transactionId: transactionId,
43
43
  formId: formId,
44
44
  fieldId: fieldId,
45
45
  answer: answer,
46
46
  time: time,
47
47
  });
48
- return tweetnacl_1.default.sign.detached.verify(tweetnacl_util_1.decodeUTF8(data), tweetnacl_util_1.decodeBase64(signature), tweetnacl_util_1.decodeBase64(_this.verificationPublicKey));
48
+ return tweetnacl_1.default.sign.detached.verify((0, tweetnacl_util_1.decodeUTF8)(data), (0, tweetnacl_util_1.decodeBase64)(signature), (0, tweetnacl_util_1.decodeBase64)(_this.verificationPublicKey));
49
49
  }
50
50
  else {
51
- console.info("Signature was expired for signatureString=\"" + signatureString + "\" signatureDate=\"" + time + "\" submissionCreatedAt=\"" + submissionCreatedAt + "\"");
51
+ console.info("Signature was expired for signatureString=\"".concat(signatureString, "\" signatureDate=\"").concat(time, "\" submissionCreatedAt=\"").concat(submissionCreatedAt, "\""));
52
52
  return false;
53
53
  }
54
54
  }
55
55
  catch (error) {
56
- console.error("An error occurred for signatureString=\"" + signatureString + "\" submissionCreatedAt=\"" + submissionCreatedAt + "\" fieldId=\"" + fieldId + "\" answer=\"" + answer + "\" error=\"" + error + "\"");
56
+ console.error("An error occurred for signatureString=\"".concat(signatureString, "\" submissionCreatedAt=\"").concat(submissionCreatedAt, "\" fieldId=\"").concat(fieldId, "\" answer=\"").concat(answer, "\" error=\"").concat(error, "\""));
57
57
  return false;
58
58
  }
59
59
  };
@@ -63,15 +63,15 @@ var Verification = /** @class */ (function () {
63
63
  throw new errors_1.MissingSecretKeyError('Provide a secret key when when initializing the Verification class to use this function.');
64
64
  }
65
65
  var time = Date.now();
66
- var data = utils_1.formatToBaseString({
66
+ var data = (0, utils_1.formatToBaseString)({
67
67
  transactionId: transactionId,
68
68
  formId: formId,
69
69
  fieldId: fieldId,
70
70
  answer: answer,
71
71
  time: time,
72
72
  });
73
- var signature = tweetnacl_1.default.sign.detached(tweetnacl_util_1.decodeUTF8(data), tweetnacl_util_1.decodeBase64(_this.verificationSecretKey));
74
- return "f=" + formId + ",v=" + transactionId + ",t=" + time + ",s=" + tweetnacl_util_1.encodeBase64(signature);
73
+ var signature = tweetnacl_1.default.sign.detached((0, tweetnacl_util_1.decodeUTF8)(data), (0, tweetnacl_util_1.decodeBase64)(_this.verificationSecretKey));
74
+ return "f=".concat(formId, ",v=").concat(transactionId, ",t=").concat(time, ",s=").concat((0, tweetnacl_util_1.encodeBase64)(signature));
75
75
  };
76
76
  this.verificationPublicKey = params === null || params === void 0 ? void 0 : params.publicKey;
77
77
  this.verificationSecretKey = params === null || params === void 0 ? void 0 : params.secretKey;
@@ -1,20 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatToBaseString = exports.isSignatureTimeValid = void 0;
3
4
  /**
4
5
  * Checks if signature was made within the given expiry range before
5
6
  * submission was created.
6
7
  * @param signatureTime ms
7
8
  * @param submissionCreatedAt ms
8
9
  */
9
- exports.isSignatureTimeValid = function (signatureTime, submissionCreatedAt, transactionExpiry) {
10
+ var isSignatureTimeValid = function (signatureTime, submissionCreatedAt, transactionExpiry) {
10
11
  var maxTime = submissionCreatedAt;
11
12
  var minTime = maxTime - transactionExpiry * 1000;
12
13
  return signatureTime > minTime && signatureTime < maxTime;
13
14
  };
15
+ exports.isSignatureTimeValid = isSignatureTimeValid;
14
16
  /**
15
17
  * Formats given data into a string for signing
16
18
  */
17
- exports.formatToBaseString = function (_a) {
19
+ var formatToBaseString = function (_a) {
18
20
  var transactionId = _a.transactionId, formId = _a.formId, fieldId = _a.fieldId, answer = _a.answer, time = _a.time;
19
- return transactionId + "." + formId + "." + fieldId + "." + answer + "." + time;
21
+ return "".concat(transactionId, ".").concat(formId, ".").concat(fieldId, ".").concat(answer, ".").concat(time);
20
22
  };
23
+ exports.formatToBaseString = formatToBaseString;