Skip to content

Commit

Permalink
wip: temporarily add dist folder
Browse files Browse the repository at this point in the history
  • Loading branch information
karrui committed Feb 18, 2021
1 parent 111f771 commit 89eddd3
Show file tree
Hide file tree
Showing 33 changed files with 1,104 additions and 1 deletion.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ web_modules/

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
Expand Down
54 changes: 54 additions & 0 deletions dist/crypto.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { DecryptParams, DecryptedContent, EncryptedFileContent } from './types';
export default class Crypto {
signingPublicKey?: string;
constructor({ signingPublicKey }?: {
signingPublicKey?: string;
});
/**
* 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. If given, will be used to signing the given msg param prior to encrypting.
* @returns The encrypted basestring.
*/
encrypt: (msg: any, encryptionPublicKey: string, signingPrivateKey?: string | undefined) => string;
/**
* 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.
* @throws {MissingPublicKeyError} if a public key is not provided when instantiating this class and is needed for verifying signed content.
*/
decrypt: (formSecretKey: string, decryptParams: DecryptParams) => DecryptedContent | null;
/**
* Generates a new keypair for encryption.
* @returns The generated keypair.
*/
generate: () => import("./types").Keypair;
/**
* 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.
*/
valid: (publicKey: string, secretKey: string) => boolean;
/**
* Encrypt given binary file with a unique keypair for each submission.
* @param binary The file to encrypt, should be a blob that is converted to 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
*/
encryptFile: (binary: Uint8Array, formPublicKey: string) => Promise<EncryptedFileContent>;
/**
* Decrypt the given encrypted file content.
* @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
*/
decryptFile: (formSecretKey: string, { submissionPublicKey, nonce, binary: encryptedBinary, }: EncryptedFileContent) => Promise<Uint8Array | null>;
}
178 changes: 178 additions & 0 deletions dist/crypto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
"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 };
};
Object.defineProperty(exports, "__esModule", { value: true });
var tweetnacl_1 = __importDefault(require("tweetnacl"));
var tweetnacl_util_1 = require("tweetnacl-util");
var validate_1 = require("./util/validate");
var errors_1 = require("./errors");
var crypto_1 = require("./util/crypto");
var Crypto = /** @class */ (function () {
function Crypto(_a) {
var _this = this;
var signingPublicKey = (_a === void 0 ? {} : _a).signingPublicKey;
/**
* 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. If given, will be used to signing the given msg param prior to encrypting.
* @returns The encrypted basestring.
*/
this.encrypt = function (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 crypto_1.encryptMessage(processedMsg, encryptionPublicKey);
};
/**
* 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.
* @throws {MissingPublicKeyError} if a public key is not provided when instantiating this class and is needed for verifying signed content.
*/
this.decrypt = function (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 = crypto_1.decryptContent(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) {
if (!_this.signingPublicKey) {
throw new errors_1.MissingPublicKeyError('Public signing key must be provided when instantiating the Crypto class in order to verify verified content');
}
// 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 = crypto_1.decryptContent(formSecretKey, verifiedContent);
if (!decryptedVerifiedContent) {
// Returns null if decrypting verified content failed.
throw new Error('Failed to decrypt verified content');
}
var decryptedVerifiedObject = crypto_1.verifySignedMessage(decryptedVerifiedContent, _this.signingPublicKey);
returnedObject.verified = decryptedVerifiedObject;
}
return returnedObject;
}
catch (err) {
// Should only throw if MissingPublicKeyError.
// This library should be able to be used to encrypt and decrypt content
// if the content does not contain verified fields.
if (err instanceof errors_1.MissingPublicKeyError) {
throw err;
}
return null;
}
};
/**
* Generates a new keypair for encryption.
* @returns The generated keypair.
*/
this.generate = crypto_1.generateKeypair;
/**
* 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.
*/
this.valid = function (publicKey, secretKey) {
var _a;
var testResponse = [];
var internalValidationVersion = 1;
var cipherResponse = _this.encrypt(testResponse, publicKey);
// Use toString here since the return should be an empty array.
return (testResponse.toString() === ((_a = _this.decrypt(secretKey, {
encryptedContent: cipherResponse,
version: internalValidationVersion,
})) === null || _a === void 0 ? void 0 : _a.responses.toString()));
};
/**
* Encrypt given binary file with a unique keypair for each submission.
* @param binary The file to encrypt, should be a blob that is converted to 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
*/
this.encryptFile = function (binary, formPublicKey) { return __awaiter(_this, void 0, void 0, function () {
var submissionKeypair, nonce;
return __generator(this, function (_a) {
submissionKeypair = this.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)),
}];
});
}); };
/**
* Decrypt the given encrypted file content.
* @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
*/
this.decryptFile = function (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))];
});
});
};
this.signingPublicKey = signingPublicKey;
}
return Crypto;
}());
exports.default = Crypto;
10 changes: 10 additions & 0 deletions dist/errors.d.ts
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, };
56 changes: 56 additions & 0 deletions dist/errors.js
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;
17 changes: 17 additions & 0 deletions dist/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PackageInitParams } from './types';
import Verification from './verification';
import Webhooks from './webhooks';
import Crypto from './crypto';
/**
* Entrypoint into the FormSG SDK
*
* @param {PackageInitParams} config Package initialization config parameters
* @param {string?} [config.mode] Optional. Initializes public key used for verifying and decrypting in this package. If `config.signingPublicKey` is given, this param will be ignored.
* @param {string?} [config.webhookSecretKey] Optional. base64 secret key for signing webhooks. If provided, enables generating signature and headers to authenticate webhook data.
* @param {VerificationOptions?} [config.verificationOptions] Optional. If provided, enables the usage of the verification module.
*/
export default function (config?: PackageInitParams): {
webhooks: Webhooks;
crypto: Crypto;
verification: Verification;
};
36 changes: 36 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var publicKey_1 = require("./util/publicKey");
var verification_1 = __importDefault(require("./verification"));
var webhooks_1 = __importDefault(require("./webhooks"));
var crypto_1 = __importDefault(require("./crypto"));
/**
* Entrypoint into the FormSG SDK
*
* @param {PackageInitParams} config Package initialization config parameters
* @param {string?} [config.mode] Optional. Initializes public key used for verifying and decrypting in this package. If `config.signingPublicKey` is given, this param will be ignored.
* @param {string?} [config.webhookSecretKey] Optional. base64 secret key for signing webhooks. If provided, enables generating signature and headers to authenticate webhook data.
* @param {VerificationOptions?} [config.verificationOptions] Optional. If provided, enables the usage of the verification module.
*/
function default_1(config) {
if (config === void 0) { config = {}; }
var webhookSecretKey = config.webhookSecretKey, mode = config.mode, verificationOptions = config.verificationOptions;
var signingPublicKey = publicKey_1.getSigningPublicKey(mode || 'production');
var verificationPublicKey = publicKey_1.getVerificationPublicKey(mode || 'production');
return {
webhooks: new webhooks_1.default({
publicKey: signingPublicKey,
secretKey: webhookSecretKey,
}),
crypto: new crypto_1.default({ signingPublicKey: signingPublicKey }),
verification: new verification_1.default({
publicKey: verificationPublicKey,
secretKey: verificationOptions === null || verificationOptions === void 0 ? void 0 : verificationOptions.secretKey,
transactionExpiry: verificationOptions === null || verificationOptions === void 0 ? void 0 : verificationOptions.transactionExpiry,
}),
};
}
exports.default = default_1;

0 comments on commit 89eddd3

Please sign in to comment.