-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: temporarily expose build folder
- Loading branch information
Showing
41 changed files
with
1,213 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,7 +80,7 @@ web_modules/ | |
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
|
||
# Gatsby files | ||
.cache/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { DecryptParams, DecryptedContent, EncryptedContent, EncryptedFileContent, Keypair, PackageInitParams } from './types'; | ||
/** | ||
* Encrypt input with a unique keypair for each submission | ||
* @param encryptionPublicKey The base-64 encoded public key for encrypting. | ||
* @param msg The message to encrypt, will be stringified. | ||
* @param signingPrivateKey Optional. Must be a base-64 encoded private key, will be used to signing the given msg param prior to encrypting. | ||
* @returns The encrypted basestring. | ||
*/ | ||
declare function encrypt(msg: any, encryptionPublicKey: string, signingPrivateKey?: string): EncryptedContent; | ||
/** | ||
* Generates a new keypair for encryption. | ||
* @returns The generated keypair. | ||
*/ | ||
declare function generate(): Keypair; | ||
/** | ||
* Helper function to encrypt file with a unique keypair for each submission. | ||
* @param binary The file to encrypt, should be a blob that is converted to { @type Uint8Array} binary | ||
* @param formPublicKey The base-64 encoded public key | ||
* @returns Promise holding the encrypted file | ||
* @throws error if any of the encrypt methods fail | ||
*/ | ||
declare function encryptFile(binary: Uint8Array, formPublicKey: string): Promise<EncryptedFileContent>; | ||
/** | ||
* Helper function to decrypt a file | ||
* @param formSecretKey Secret key as a base-64 string | ||
* @param encrypted Object returned from encryptFile function | ||
* @param encrypted.submissionPublicKey The submission public key as a base-64 string | ||
* @param encrypted.nonce The nonce as a base-64 string | ||
* @param encrypted.blob The encrypted file as a Blob object | ||
*/ | ||
declare function decryptFile(formSecretKey: string, { submissionPublicKey, nonce, binary: encryptedBinary }: EncryptedFileContent): Promise<Uint8Array | null>; | ||
declare const _default: ({ mode }: Pick<PackageInitParams, "mode" | "verificationOptions">) => { | ||
encrypt: typeof encrypt; | ||
decrypt: (formSecretKey: string, decryptParams: DecryptParams) => DecryptedContent | null; | ||
generate: typeof generate; | ||
valid: (publicKey: string, secretKey: string) => boolean; | ||
encryptFile: typeof encryptFile; | ||
decryptFile: typeof decryptFile; | ||
}; | ||
/** | ||
* Provider that accepts configuration before returning the crypto module to | ||
* init. | ||
*/ | ||
export = _default; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var tweetnacl_1 = __importDefault(require("tweetnacl")); | ||
var tweetnacl_util_1 = require("tweetnacl-util"); | ||
var publicKey_1 = require("./util/publicKey"); | ||
var validate_1 = require("./util/validate"); | ||
/** | ||
* Encrypt input with a unique keypair for each submission | ||
* @param encryptionPublicKey The base-64 encoded public key for encrypting. | ||
* @param msg The message to encrypt, will be stringified. | ||
* @param signingPrivateKey Optional. Must be a base-64 encoded private key, will be used to signing the given msg param prior to encrypting. | ||
* @returns The encrypted basestring. | ||
*/ | ||
function encrypt(msg, encryptionPublicKey, signingPrivateKey) { | ||
var processedMsg = tweetnacl_util_1.decodeUTF8(JSON.stringify(msg)); | ||
if (signingPrivateKey) { | ||
processedMsg = tweetnacl_1.default.sign(processedMsg, tweetnacl_util_1.decodeBase64(signingPrivateKey)); | ||
} | ||
return _encrypt(processedMsg, encryptionPublicKey); | ||
} | ||
/** | ||
* Helper function to encrypt input with a unique keypair for each submission. | ||
* @param msg The message to encrypt | ||
* @param theirPublicKey The base-64 encoded public key | ||
* @returns The encrypted basestring | ||
* @throws error if any of the encrypt methods fail | ||
*/ | ||
function _encrypt(msg, theirPublicKey) { | ||
var submissionKeypair = generate(); | ||
var nonce = tweetnacl_1.default.randomBytes(24); | ||
var encrypted = tweetnacl_util_1.encodeBase64(tweetnacl_1.default.box(msg, nonce, tweetnacl_util_1.decodeBase64(theirPublicKey), tweetnacl_util_1.decodeBase64(submissionKeypair.secretKey))); | ||
return submissionKeypair.publicKey + ";" + tweetnacl_util_1.encodeBase64(nonce) + ":" + encrypted; | ||
} | ||
/** | ||
* Helper method to decrypt an encrypted submission. | ||
* @param formPrivateKey base64 | ||
* @param encryptedContent encrypted string encoded in base64 | ||
* @return The decrypted content, or null if decryption failed. | ||
*/ | ||
function _decrypt(formPrivateKey, encryptedContent) { | ||
try { | ||
var _a = encryptedContent.split(';'), submissionPublicKey = _a[0], nonceEncrypted = _a[1]; | ||
var _b = nonceEncrypted.split(':').map(tweetnacl_util_1.decodeBase64), nonce = _b[0], encrypted = _b[1]; | ||
return tweetnacl_1.default.box.open(encrypted, nonce, tweetnacl_util_1.decodeBase64(submissionPublicKey), tweetnacl_util_1.decodeBase64(formPrivateKey)); | ||
} | ||
catch (err) { | ||
return null; | ||
} | ||
} | ||
/** | ||
* Helper method to verify a signed message. | ||
* @param msg the message to verify | ||
* @param publicKey the public key to authenticate the signed message with | ||
* @returns the signed message if successful, else an error will be thrown. | ||
*/ | ||
function _verifySignedMessage(msg, publicKey) { | ||
var openedMessage = tweetnacl_1.default.sign.open(msg, tweetnacl_util_1.decodeBase64(publicKey)); | ||
if (!openedMessage) | ||
throw new Error('Failed to open signed message with given public key'); | ||
return JSON.parse(tweetnacl_util_1.encodeUTF8(openedMessage)); | ||
} | ||
/** | ||
* Higher order function returning a function to decrypt an encrypted | ||
* submission. | ||
* @param signingPublicKey The public key to open verified objects that was signed with the private key passed to this library. | ||
*/ | ||
function decrypt(signingPublicKey) { | ||
/** | ||
* Decrypts an encrypted submission and returns it. | ||
* @param formSecretKey The base-64 secret key of the form to decrypt with. | ||
* @param decryptParams The params containing encrypted content and information. | ||
* @param decryptParams.encryptedContent The encrypted content encoded with base-64. | ||
* @param decryptParams.version The version of the payload. Used to determine the decryption process to decrypt the content with. | ||
* @param decryptParams.verifiedContent Optional. The encrypted and signed verified content. If given, the signingPublicKey will be used to attempt to open the signed message. | ||
* @returns The decrypted content if successful. Else, null will be returned. | ||
*/ | ||
function _internalDecrypt(formSecretKey, decryptParams) { | ||
try { | ||
var encryptedContent = decryptParams.encryptedContent, verifiedContent = decryptParams.verifiedContent, version = decryptParams.version; | ||
// Do not return the transformed object in `_decrypt` function as a signed | ||
// object is not encoded in UTF8 and is encoded in Base-64 instead. | ||
var decryptedContent = _decrypt(formSecretKey, encryptedContent); | ||
if (!decryptedContent) { | ||
throw new Error('Failed to decrypt content'); | ||
} | ||
var decryptedObject = JSON.parse(tweetnacl_util_1.encodeUTF8(decryptedContent)); | ||
if (!validate_1.determineIsFormFields(decryptedObject)) { | ||
throw new Error('Decrypted object does not fit expected shape'); | ||
} | ||
var returnedObject = { | ||
responses: decryptedObject, | ||
}; | ||
if (verifiedContent) { | ||
// Only care if it is the correct shape if verifiedContent exists, since | ||
// we need to append it to the end. | ||
// Decrypted message must be able to be authenticated by the public key. | ||
var decryptedVerifiedContent = _decrypt(formSecretKey, verifiedContent); | ||
if (!decryptedVerifiedContent) { | ||
// Returns null if verification for decrypt failed. | ||
throw new Error('Verification failed for signature'); | ||
} | ||
var decryptedVerifiedObject = _verifySignedMessage(decryptedVerifiedContent, signingPublicKey); | ||
returnedObject.verified = decryptedVerifiedObject; | ||
} | ||
return returnedObject; | ||
} | ||
catch (err) { | ||
return null; | ||
} | ||
} | ||
return _internalDecrypt; | ||
} | ||
/** | ||
* Generates a new keypair for encryption. | ||
* @returns The generated keypair. | ||
*/ | ||
function generate() { | ||
var kp = tweetnacl_1.default.box.keyPair(); | ||
return { | ||
publicKey: tweetnacl_util_1.encodeBase64(kp.publicKey), | ||
secretKey: tweetnacl_util_1.encodeBase64(kp.secretKey), | ||
}; | ||
} | ||
function valid(signingPublicKey) { | ||
/** | ||
* Returns true if a pair of public & secret keys are associated with each other | ||
* @param publicKey The public key to verify against. | ||
* @param secretKey The private key to verify against. | ||
*/ | ||
function _internalValid(publicKey, secretKey) { | ||
var _a; | ||
var testResponse = []; | ||
var internalValidationVersion = 1; | ||
try { | ||
var cipherResponse = encrypt(testResponse, publicKey); | ||
// Use toString here since the return should be an empty array. | ||
return (testResponse.toString() === ((_a = decrypt(signingPublicKey)(secretKey, { | ||
encryptedContent: cipherResponse, | ||
version: internalValidationVersion, | ||
})) === null || _a === void 0 ? void 0 : _a.responses.toString())); | ||
} | ||
catch (err) { | ||
return false; | ||
} | ||
} | ||
return _internalValid; | ||
} | ||
/** | ||
* Helper function to encrypt file with a unique keypair for each submission. | ||
* @param binary The file to encrypt, should be a blob that is converted to { @type Uint8Array} binary | ||
* @param formPublicKey The base-64 encoded public key | ||
* @returns Promise holding the encrypted file | ||
* @throws error if any of the encrypt methods fail | ||
*/ | ||
function encryptFile(binary, formPublicKey) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var submissionKeypair, nonce; | ||
return __generator(this, function (_a) { | ||
submissionKeypair = generate(); | ||
nonce = tweetnacl_1.default.randomBytes(24); | ||
return [2 /*return*/, { | ||
submissionPublicKey: submissionKeypair.publicKey, | ||
nonce: tweetnacl_util_1.encodeBase64(nonce), | ||
binary: tweetnacl_1.default.box(binary, nonce, tweetnacl_util_1.decodeBase64(formPublicKey), tweetnacl_util_1.decodeBase64(submissionKeypair.secretKey)), | ||
}]; | ||
}); | ||
}); | ||
} | ||
/** | ||
* Helper function to decrypt a file | ||
* @param formSecretKey Secret key as a base-64 string | ||
* @param encrypted Object returned from encryptFile function | ||
* @param encrypted.submissionPublicKey The submission public key as a base-64 string | ||
* @param encrypted.nonce The nonce as a base-64 string | ||
* @param encrypted.blob The encrypted file as a Blob object | ||
*/ | ||
function decryptFile(formSecretKey, _a) { | ||
var submissionPublicKey = _a.submissionPublicKey, nonce = _a.nonce, encryptedBinary = _a.binary; | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_b) { | ||
return [2 /*return*/, tweetnacl_1.default.box.open(encryptedBinary, tweetnacl_util_1.decodeBase64(nonce), tweetnacl_util_1.decodeBase64(submissionPublicKey), tweetnacl_util_1.decodeBase64(formSecretKey))]; | ||
}); | ||
}); | ||
} | ||
module.exports = function (_a) { | ||
var mode = _a.mode; | ||
var signingPublicKey = publicKey_1.getPublicKey(mode); | ||
return { | ||
encrypt: encrypt, | ||
decrypt: decrypt(signingPublicKey), | ||
generate: generate, | ||
valid: valid(signingPublicKey), | ||
encryptFile: encryptFile, | ||
decryptFile: decryptFile, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
declare class MissingSecretKeyError extends Error { | ||
constructor(message?: string); | ||
} | ||
declare class MissingPublicKeyError extends Error { | ||
constructor(message?: string); | ||
} | ||
declare class WebhookAuthenticateError extends Error { | ||
constructor(message: string); | ||
} | ||
export { MissingSecretKeyError, MissingPublicKeyError, WebhookAuthenticateError, }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var MissingSecretKeyError = /** @class */ (function (_super) { | ||
__extends(MissingSecretKeyError, _super); | ||
function MissingSecretKeyError(message) { | ||
if (message === void 0) { message = 'Provide a secret key when initializing the FormSG SDK to use this function.'; } | ||
var _this = _super.call(this, message) || this; | ||
_this.name = _this.constructor.name; | ||
// Set the prototype explicitly. | ||
// See https://github.com/facebook/jest/issues/8279 | ||
Object.setPrototypeOf(_this, MissingSecretKeyError.prototype); | ||
return _this; | ||
} | ||
return MissingSecretKeyError; | ||
}(Error)); | ||
exports.MissingSecretKeyError = MissingSecretKeyError; | ||
var MissingPublicKeyError = /** @class */ (function (_super) { | ||
__extends(MissingPublicKeyError, _super); | ||
function MissingPublicKeyError(message) { | ||
if (message === void 0) { message = 'Provide a public key when initializing the FormSG SDK to use this function.'; } | ||
var _this = _super.call(this, message) || this; | ||
_this.name = _this.constructor.name; | ||
// Set the prototype explicitly. | ||
// See https://github.com/facebook/jest/issues/8279 | ||
Object.setPrototypeOf(_this, MissingPublicKeyError.prototype); | ||
return _this; | ||
} | ||
return MissingPublicKeyError; | ||
}(Error)); | ||
exports.MissingPublicKeyError = MissingPublicKeyError; | ||
var WebhookAuthenticateError = /** @class */ (function (_super) { | ||
__extends(WebhookAuthenticateError, _super); | ||
function WebhookAuthenticateError(message) { | ||
var _this = _super.call(this, message) || this; | ||
_this.name = _this.constructor.name; | ||
// Set the prototype explicitly. | ||
// See https://github.com/facebook/jest/issues/8279 | ||
Object.setPrototypeOf(_this, WebhookAuthenticateError.prototype); | ||
return _this; | ||
} | ||
return WebhookAuthenticateError; | ||
}(Error)); | ||
exports.WebhookAuthenticateError = WebhookAuthenticateError; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { PackageInitParams } from './types'; | ||
declare const _default: (options?: PackageInitParams) => { | ||
webhooks: { | ||
authenticate: (header: string, uri: string) => void; | ||
generateSignature: (({ uri, submissionId, formId, epoch, }: { | ||
uri: string; | ||
submissionId: Object; | ||
formId: string; | ||
epoch: number; | ||
}) => string) | (() => void); | ||
constructHeader: (({ epoch, submissionId, formId, signature, }: { | ||
epoch: number; | ||
submissionId: string; | ||
formId: string; | ||
signature: string; | ||
}) => string) | (() => void); | ||
}; | ||
crypto: { | ||
encrypt: (msg: any, encryptionPublicKey: string, signingPrivateKey?: string | undefined) => string; | ||
decrypt: (formSecretKey: string, decryptParams: import("./types").DecryptParams) => import("./types").DecryptedContent | null; | ||
generate: () => import("./types").Keypair; | ||
valid: (publicKey: string, secretKey: string) => boolean; | ||
encryptFile: (binary: Uint8Array, formPublicKey: string) => Promise<import("./types").EncryptedFileContent>; | ||
decryptFile: (formSecretKey: string, { submissionPublicKey, nonce, binary: encryptedBinary }: import("./types").EncryptedFileContent) => Promise<Uint8Array | null>; | ||
}; | ||
verification: { | ||
authenticate: Function; | ||
generateSignature: ({ transactionId, formId, fieldId, answer, }: import("./types").VerificationSignatureOptions) => string; | ||
} | { | ||
authenticate?: undefined; | ||
generateSignature?: undefined; | ||
}; | ||
}; | ||
/** | ||
* Entrypoint into the FormSG SDK | ||
* @param {Object} options | ||
* @param {string} [options.mode] If set to 'staging' this will initialise | ||
* the SDK for the FormSG staging environment | ||
* @param {string} [options.webhookSecretKey] Optional base64 secret key for signing webhooks | ||
*/ | ||
export = _default; |
Oops, something went wrong.