@opengovsg/formsg-sdk 0.8.4-beta.0 → 0.10.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/.eslintrc +75 -0
- package/.github/workflows/ci.yml +51 -0
- package/CHANGELOG.md +120 -0
- package/README.md +33 -20
- package/dist/crypto.d.ts +9 -1
- package/dist/crypto.js +78 -2
- package/dist/errors.d.ts +4 -1
- package/dist/errors.js +11 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/resource/signing-keys.d.ts +1 -0
- package/dist/resource/signing-keys.js +3 -2
- package/dist/resource/verification-keys.d.ts +1 -0
- package/dist/resource/verification-keys.js +3 -2
- package/dist/types.d.ts +18 -0
- package/dist/util/crypto.d.ts +14 -1
- package/dist/util/crypto.js +20 -1
- package/dist/util/publicKey.js +2 -0
- package/dist/util/validate.js +3 -1
- package/dist/util/webhooks.js +1 -1
- package/dist/verification/index.d.ts +1 -1
- package/dist/webhooks.js +1 -1
- package/package.json +19 -8
package/.eslintrc
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"commonjs": true,
|
|
4
|
+
"es6": true,
|
|
5
|
+
"node": true
|
|
6
|
+
},
|
|
7
|
+
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
|
|
8
|
+
"parserOptions": {
|
|
9
|
+
"ecmaVersion": 2018
|
|
10
|
+
},
|
|
11
|
+
"overrides": [
|
|
12
|
+
{
|
|
13
|
+
"files": ["*.ts"],
|
|
14
|
+
"parser": "@typescript-eslint/parser",
|
|
15
|
+
"parserOptions": {
|
|
16
|
+
"sourceType": "module",
|
|
17
|
+
"ecmaFeatures": {
|
|
18
|
+
"modules": true
|
|
19
|
+
},
|
|
20
|
+
"project": "tsconfig.json"
|
|
21
|
+
},
|
|
22
|
+
"plugins": [
|
|
23
|
+
"@typescript-eslint",
|
|
24
|
+
"import",
|
|
25
|
+
"simple-import-sort",
|
|
26
|
+
"typesafe"
|
|
27
|
+
],
|
|
28
|
+
"extends": ["plugin:@typescript-eslint/recommended"],
|
|
29
|
+
"rules": {
|
|
30
|
+
// Rules for auto sort of imports
|
|
31
|
+
"simple-import-sort/imports": [
|
|
32
|
+
"error",
|
|
33
|
+
{
|
|
34
|
+
"groups": [
|
|
35
|
+
// Side effect imports.
|
|
36
|
+
["^\\u0000"],
|
|
37
|
+
// Packages.
|
|
38
|
+
// Things that start with a letter (or digit or underscore), or
|
|
39
|
+
// `@` followed by a letter.
|
|
40
|
+
["^@?\\w"],
|
|
41
|
+
// Root imports
|
|
42
|
+
["^(src)(/.*|$)"],
|
|
43
|
+
["^(tests)(/.*|$)"],
|
|
44
|
+
// Parent imports. Put `..` last.
|
|
45
|
+
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
|
|
46
|
+
// Other relative imports. Put same-folder imports and `.` last.
|
|
47
|
+
["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"]
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"sort-imports": "off",
|
|
52
|
+
"import/order": "off",
|
|
53
|
+
"import/first": "error",
|
|
54
|
+
"import/newline-after-import": "error",
|
|
55
|
+
"import/no-duplicates": "error",
|
|
56
|
+
"@typescript-eslint/no-floating-promises": 2,
|
|
57
|
+
"@typescript-eslint/no-unused-vars": 2,
|
|
58
|
+
// Disabled pending refactoring of two helper functions
|
|
59
|
+
// "typesafe/no-throw-sync-func": "error"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{ "files": ["*.spec.ts"], "extends": ["plugin:jest/recommended"] },
|
|
63
|
+
{
|
|
64
|
+
"files": ["*.ts", "*.js"],
|
|
65
|
+
"excludedFiles": ["**/*.spec.ts", "**/.spec.js", "**/__tests__/**/*.ts"],
|
|
66
|
+
"rules": {
|
|
67
|
+
"@typescript-eslint/no-non-null-assertion": "error"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"rules": {
|
|
72
|
+
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
|
73
|
+
"no-console": "warn"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, reopened]
|
|
6
|
+
jobs:
|
|
7
|
+
build:
|
|
8
|
+
name: build
|
|
9
|
+
runs-on: ubuntu-18.04
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v2
|
|
12
|
+
- name: Use Node.js
|
|
13
|
+
uses: actions/setup-node@v1
|
|
14
|
+
with:
|
|
15
|
+
node-version: '10.x'
|
|
16
|
+
- name: Cache Node.js modules
|
|
17
|
+
uses: actions/cache@v2
|
|
18
|
+
with:
|
|
19
|
+
# npm cache files are stored in `~/.npm` on Linux/macOS
|
|
20
|
+
path: ~/.npm
|
|
21
|
+
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
22
|
+
restore-keys: |
|
|
23
|
+
${{ runner.OS }}-node-
|
|
24
|
+
${{ runner.OS }}-
|
|
25
|
+
- run: npm ci
|
|
26
|
+
- run: npx lockfile-lint --type npm --path package-lock.json --validate-https --allowed-hosts npm
|
|
27
|
+
- run: npm run build
|
|
28
|
+
test:
|
|
29
|
+
name: test
|
|
30
|
+
runs-on: ubuntu-18.04
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v2
|
|
33
|
+
- name: Use Node.js
|
|
34
|
+
uses: actions/setup-node@v1
|
|
35
|
+
with:
|
|
36
|
+
node-version: '10.x'
|
|
37
|
+
- name: Cache Node.js modules
|
|
38
|
+
uses: actions/cache@v2
|
|
39
|
+
with:
|
|
40
|
+
# npm cache files are stored in `~/.npm` on Linux/macOS
|
|
41
|
+
path: ~/.npm
|
|
42
|
+
key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
43
|
+
restore-keys: |
|
|
44
|
+
${{ runner.OS }}-node-
|
|
45
|
+
${{ runner.OS }}-
|
|
46
|
+
- run: npm ci
|
|
47
|
+
- run: npm run test-ci
|
|
48
|
+
- name: Submit test coverage to Coveralls
|
|
49
|
+
uses: coverallsapp/github-action@v1.1.2
|
|
50
|
+
with:
|
|
51
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
### Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
|
4
|
+
|
|
5
|
+
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
|
+
|
|
7
|
+
#### [v0.10.0](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.9.0...v0.10.0)
|
|
8
|
+
|
|
9
|
+
> 16 December 2022
|
|
10
|
+
|
|
11
|
+
- fix: allow empty field titles in decrypted responses [`#86`](https://github.com/opengovsg/formsg-javascript-sdk/pull/86)
|
|
12
|
+
- chore: run npm audit fix and update relevant deps [`#80`](https://github.com/opengovsg/formsg-javascript-sdk/pull/80)
|
|
13
|
+
- chore(deps): Upgrade vulnerable axios version [`#78`](https://github.com/opengovsg/formsg-javascript-sdk/pull/78)
|
|
14
|
+
- chore: merge v0.9.0 into develop [`#76`](https://github.com/opengovsg/formsg-javascript-sdk/pull/76)
|
|
15
|
+
- fix: run npm audit fix so typescript packages are the correct versions [`2bdbf89`](https://github.com/opengovsg/formsg-javascript-sdk/commit/2bdbf897614833cc50605554ddaa82ea567b8a09)
|
|
16
|
+
- chore: bump version to v0.10.0 [`e094041`](https://github.com/opengovsg/formsg-javascript-sdk/commit/e0940414e529012afc03c54165f82e9f5ce16b12)
|
|
17
|
+
|
|
18
|
+
#### [v0.9.0](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.8.2...v0.9.0)
|
|
19
|
+
|
|
20
|
+
> 16 December 2022
|
|
21
|
+
|
|
22
|
+
- build: add separate keypairs for dev environment [`#73`](https://github.com/opengovsg/formsg-javascript-sdk/pull/73)
|
|
23
|
+
- docs: specify version for attachment functionality [`#72`](https://github.com/opengovsg/formsg-javascript-sdk/pull/72)
|
|
24
|
+
- build(ci): migrate to GitHub Actions [`#70`](https://github.com/opengovsg/formsg-javascript-sdk/pull/70)
|
|
25
|
+
- refactor(crypto): minor refactor of decryptWithAttachments [`#69`](https://github.com/opengovsg/formsg-javascript-sdk/pull/69)
|
|
26
|
+
- feat: Adding eslint functionality for the repository [`#66`](https://github.com/opengovsg/formsg-javascript-sdk/pull/66)
|
|
27
|
+
- build(deps): bump lodash from 4.17.19 to 4.17.21 [`#64`](https://github.com/opengovsg/formsg-javascript-sdk/pull/64)
|
|
28
|
+
- add downloadAndDecryptAttachments for downloading and decrypting attachments [`#62`](https://github.com/opengovsg/formsg-javascript-sdk/pull/62)
|
|
29
|
+
- build(deps): bump y18n from 4.0.0 to 4.0.1 [`#59`](https://github.com/opengovsg/formsg-javascript-sdk/pull/59)
|
|
30
|
+
- Update README.md [`#61`](https://github.com/opengovsg/formsg-javascript-sdk/pull/61)
|
|
31
|
+
- build: merge Release 0.8.4 back to develop branch [`#58`](https://github.com/opengovsg/formsg-javascript-sdk/pull/58)
|
|
32
|
+
- build: release v0.8.4-beta.0 [`#56`](https://github.com/opengovsg/formsg-javascript-sdk/pull/56)
|
|
33
|
+
- Revert "build(npm): update repo entry (#43)" [`#55`](https://github.com/opengovsg/formsg-javascript-sdk/pull/55)
|
|
34
|
+
- fix: update .npmignore to ignore misc unneeded files [`#54`](https://github.com/opengovsg/formsg-javascript-sdk/pull/54)
|
|
35
|
+
- ref: use mode init parameter again [`#52`](https://github.com/opengovsg/formsg-javascript-sdk/pull/52)
|
|
36
|
+
- chore: Update JSDoc and print warning message if deprecated mode parameter is used [`#51`](https://github.com/opengovsg/formsg-javascript-sdk/pull/51)
|
|
37
|
+
- fix(FormField): account for table responses [`#44`](https://github.com/opengovsg/formsg-javascript-sdk/pull/44)
|
|
38
|
+
- build(npm): update repo entry [`#43`](https://github.com/opengovsg/formsg-javascript-sdk/pull/43)
|
|
39
|
+
- feat: add more webhook tests to check for undefined params [`#41`](https://github.com/opengovsg/formsg-javascript-sdk/pull/41)
|
|
40
|
+
- Bump lodash from 4.17.15 to 4.17.19 [`#42`](https://github.com/opengovsg/formsg-javascript-sdk/pull/42)
|
|
41
|
+
- fix: JSON body parser required for demo code to work [`#40`](https://github.com/opengovsg/formsg-javascript-sdk/pull/40)
|
|
42
|
+
- refactor: update verification HOF to Verification class [`#38`](https://github.com/opengovsg/formsg-javascript-sdk/pull/38)
|
|
43
|
+
- refactor: update crypto HOF to Crypto class [`#36`](https://github.com/opengovsg/formsg-javascript-sdk/pull/36)
|
|
44
|
+
- refactor: update webhooks HOF to Webhooks class [`#34`](https://github.com/opengovsg/formsg-javascript-sdk/pull/34)
|
|
45
|
+
- docs: fix code snippet typos [`#37`](https://github.com/opengovsg/formsg-javascript-sdk/pull/37)
|
|
46
|
+
- feat: add publicKey param to package initialization parameters [`#33`](https://github.com/opengovsg/formsg-javascript-sdk/pull/33)
|
|
47
|
+
- chore: add `test-ci` script for Travis to run instead of `test` [`#32`](https://github.com/opengovsg/formsg-javascript-sdk/pull/32)
|
|
48
|
+
- Release 0.8.3 - Allow tolerance for clock drift when authenticating webhooks [`#47`](https://github.com/opengovsg/formsg-javascript-sdk/pull/47)
|
|
49
|
+
- fix(epoch): allow for possible clock drift [`a3ce917`](https://github.com/opengovsg/formsg-javascript-sdk/commit/a3ce917c6c38a387edcfad06ae5176b1f92b0a46)
|
|
50
|
+
- fix(epoch): allow for possible clock drift [`5ba253d`](https://github.com/opengovsg/formsg-javascript-sdk/commit/5ba253d61d04d3082f4d752ecfc9efd3639acc0f)
|
|
51
|
+
- chore: bump version to 0.9.0 [`32111b1`](https://github.com/opengovsg/formsg-javascript-sdk/commit/32111b1a2c85955a33d478dbc06966dda7261e33)
|
|
52
|
+
|
|
53
|
+
#### [v0.8.2](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.4.1...v0.8.2)
|
|
54
|
+
|
|
55
|
+
> 4 June 2020
|
|
56
|
+
|
|
57
|
+
- Release v0.8.2 - Patch for encrypting non-UTF8 characters [`#35`](https://github.com/opengovsg/formsg-javascript-sdk/pull/35)
|
|
58
|
+
- Release v0.8.1 - Export types [`#29`](https://github.com/opengovsg/formsg-javascript-sdk/pull/29)
|
|
59
|
+
- Fix: Export declared types in the package [`#28`](https://github.com/opengovsg/formsg-javascript-sdk/pull/28)
|
|
60
|
+
- Replace tweetnacl-util with StableLib [`#27`](https://github.com/opengovsg/formsg-javascript-sdk/pull/27)
|
|
61
|
+
- v0.8.0 - Update decrypt signature [`#25`](https://github.com/opengovsg/formsg-javascript-sdk/pull/25)
|
|
62
|
+
- Test and build coverage badges with TravsiCI and Coveralls.io [`#23`](https://github.com/opengovsg/formsg-javascript-sdk/pull/23)
|
|
63
|
+
- chore: update README for increased clarity on decrypt [`#22`](https://github.com/opengovsg/formsg-javascript-sdk/pull/22)
|
|
64
|
+
- v0.7.0 - Verification module for SDK [`#19`](https://github.com/opengovsg/formsg-javascript-sdk/pull/19)
|
|
65
|
+
- fix: use req.get() in README sample code [`#21`](https://github.com/opengovsg/formsg-javascript-sdk/pull/21)
|
|
66
|
+
- Enforce minimum level of test coverage [`#20`](https://github.com/opengovsg/formsg-javascript-sdk/pull/20)
|
|
67
|
+
- Update encrypt/decryptFile function signature from blob to UInt8Array [`#18`](https://github.com/opengovsg/formsg-javascript-sdk/pull/18)
|
|
68
|
+
- Utility functions for attachments [`#17`](https://github.com/opengovsg/formsg-javascript-sdk/pull/17)
|
|
69
|
+
- Replace Joi with custom validation [`#16`](https://github.com/opengovsg/formsg-javascript-sdk/pull/16)
|
|
70
|
+
- Link GitHub to package.json [`#15`](https://github.com/opengovsg/formsg-javascript-sdk/pull/15)
|
|
71
|
+
- Fix broken links in readme [`#14`](https://github.com/opengovsg/formsg-javascript-sdk/pull/14)
|
|
72
|
+
- Extend crypto module for verified fields and migrate to TypeScript [`#12`](https://github.com/opengovsg/formsg-javascript-sdk/pull/12)
|
|
73
|
+
- Patch readme sample code [`#11`](https://github.com/opengovsg/formsg-javascript-sdk/pull/11)
|
|
74
|
+
|
|
75
|
+
#### [v0.4.1](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.4.0...v0.4.1)
|
|
76
|
+
|
|
77
|
+
> 30 March 2020
|
|
78
|
+
|
|
79
|
+
- Release v0.4.1 - Remove dangling reference to source in require [`#10`](https://github.com/opengovsg/formsg-javascript-sdk/pull/10)
|
|
80
|
+
|
|
81
|
+
#### [v0.4.0](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.3.2...v0.4.0)
|
|
82
|
+
|
|
83
|
+
> 30 March 2020
|
|
84
|
+
|
|
85
|
+
- Pre-publish transpile pipeline with Babel [`#9`](https://github.com/opengovsg/formsg-javascript-sdk/pull/9)
|
|
86
|
+
|
|
87
|
+
#### [v0.3.2](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.3.1...v0.3.2)
|
|
88
|
+
|
|
89
|
+
> 30 March 2020
|
|
90
|
+
|
|
91
|
+
- Avoid default arguments in destructuring [`#8`](https://github.com/opengovsg/formsg-javascript-sdk/pull/8)
|
|
92
|
+
|
|
93
|
+
#### [v0.3.1](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.3.0...v0.3.1)
|
|
94
|
+
|
|
95
|
+
> 30 March 2020
|
|
96
|
+
|
|
97
|
+
- Destructure options in the function body [`#7`](https://github.com/opengovsg/formsg-javascript-sdk/pull/7)
|
|
98
|
+
|
|
99
|
+
#### [v0.3.0](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.2.0...v0.3.0)
|
|
100
|
+
|
|
101
|
+
> 24 March 2020
|
|
102
|
+
|
|
103
|
+
- Release 0.3.0 [`#5`](https://github.com/opengovsg/formsg-javascript-sdk/pull/5)
|
|
104
|
+
- Add cryptographic functions to SDK [`#4`](https://github.com/opengovsg/formsg-javascript-sdk/pull/4)
|
|
105
|
+
- Update readme to clarify that this repository is the SDK and not the FormSG system. [`#3`](https://github.com/opengovsg/formsg-javascript-sdk/pull/3)
|
|
106
|
+
|
|
107
|
+
#### [v0.2.0](https://github.com/opengovsg/formsg-javascript-sdk/compare/v0.1.1...v0.2.0)
|
|
108
|
+
|
|
109
|
+
> 2 March 2020
|
|
110
|
+
|
|
111
|
+
- Version 0.2.0 - Add signing functions, end-to-end testing [`#2`](https://github.com/opengovsg/formsg-javascript-sdk/pull/2)
|
|
112
|
+
|
|
113
|
+
#### v0.1.1
|
|
114
|
+
|
|
115
|
+
> 2 March 2020
|
|
116
|
+
|
|
117
|
+
- Version 0.1.1 - Readme, configuration bugfix [`#1`](https://github.com/opengovsg/formsg-javascript-sdk/pull/1)
|
|
118
|
+
- Add signature authentication [`a23a6ff`](https://github.com/opengovsg/formsg-javascript-sdk/commit/a23a6ffee1aaa65f805207b3f7ed17ed05590010)
|
|
119
|
+
- gitignore [`1b288fa`](https://github.com/opengovsg/formsg-javascript-sdk/commit/1b288fa9cff6df70efb09bf477570159516605e1)
|
|
120
|
+
- install dependencies [`d8fc078`](https://github.com/opengovsg/formsg-javascript-sdk/commit/d8fc078b29ffb0043adbb105fe4a39abed5a8cf9)
|
package/README.md
CHANGED
|
@@ -47,6 +47,9 @@ const POST_URI = 'https://my-domain.com/submissions'
|
|
|
47
47
|
// Your form's secret key downloaded from FormSG upon form creation
|
|
48
48
|
const formSecretKey = process.env.FORM_SECRET_KEY
|
|
49
49
|
|
|
50
|
+
// Set to true if you need to download and decrypt attachments from submissions
|
|
51
|
+
const HAS_ATTACHMENTS = false
|
|
52
|
+
|
|
50
53
|
app.post(
|
|
51
54
|
'/submissions',
|
|
52
55
|
// Endpoint authentication by verifying signatures
|
|
@@ -62,20 +65,12 @@ app.post(
|
|
|
62
65
|
// Parse JSON from raw request body
|
|
63
66
|
express.json(),
|
|
64
67
|
// Decrypt the submission
|
|
65
|
-
function (req, res, next) {
|
|
66
|
-
// `
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// }
|
|
72
|
-
/** @type {{responses: FormField[], verified?: Record<string, any>}} */
|
|
73
|
-
const submission = formsg.crypto.decrypt(
|
|
74
|
-
formSecretKey,
|
|
75
|
-
// If `verifiedContent` is provided in `req.body.data`, the return object
|
|
76
|
-
// will include a verified key.
|
|
77
|
-
req.body.data
|
|
78
|
-
)
|
|
68
|
+
async function (req, res, next) {
|
|
69
|
+
// If `verifiedContent` is provided in `req.body.data`, the return object
|
|
70
|
+
// will include a verified key.
|
|
71
|
+
const submission = HAS_ATTACHMENTS
|
|
72
|
+
? await formsg.crypto.decryptWithAttachments(formSecretKey, req.body.data)
|
|
73
|
+
: formsg.crypto.decrypt(formSecretKey, req.body.data)
|
|
79
74
|
|
|
80
75
|
// If the decryption failed, submission will be `null`.
|
|
81
76
|
if (submission) {
|
|
@@ -97,12 +92,13 @@ The underlying cryptosystem is `x25519-xsalsa20-poly1305` which is implemented b
|
|
|
97
92
|
|
|
98
93
|
### Format of Submission Response
|
|
99
94
|
|
|
100
|
-
| Key
|
|
101
|
-
|
|
|
102
|
-
| formId
|
|
103
|
-
| submissionId
|
|
104
|
-
| encryptedContent
|
|
105
|
-
| created
|
|
95
|
+
| Key | Type | Description |
|
|
96
|
+
| ---------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| formId | string | Unique form identifier. |
|
|
98
|
+
| submissionId | string | Unique response identifier, displayed as 'Response ID' to form respondents |
|
|
99
|
+
| encryptedContent | string | The encrypted submission in base64. |
|
|
100
|
+
| created | string | Creation timestamp. |
|
|
101
|
+
| attachmentDownloadUrls | Record<string, string> | (Optional) Records containing field IDs and URLs where encrypted uploaded attachments can be downloaded. |
|
|
106
102
|
|
|
107
103
|
### Format of Decrypted Submissions
|
|
108
104
|
|
|
@@ -158,6 +154,23 @@ If the decrypted content is the correct shape, then:
|
|
|
158
154
|
verified content. **If the verification fails, `null` is returned, even if
|
|
159
155
|
`decryptParams.encryptedContent` was successfully decrypted.**
|
|
160
156
|
|
|
157
|
+
### Processing Attachments
|
|
158
|
+
|
|
159
|
+
`formsg.crypto.decryptWithAttachments(formSecretKey: string, decryptParams: DecryptParams)` (available from version 0.9.0 onwards) behaves similarly except it will return a `Promise<DecryptedContentAndAttachments | null>`.
|
|
160
|
+
|
|
161
|
+
`DecryptedContentAndAttachments` is an object containing two fields:
|
|
162
|
+
|
|
163
|
+
- `content`: the standard form decrypted responses (same as the return type of `formsg.crypto.decrypt`)
|
|
164
|
+
- `attachments`: A `Record<string, DecryptedFile>` containing a map of field ids of the attachment fields to a object containing the original user supplied filename and a `Uint8Array` containing the contents of the uploaded file.
|
|
165
|
+
|
|
166
|
+
If the contents of any file fails to decrypt or there is a mismatch between the attachments and submission (e.g. the submission doesn't contain the original file name), then `null` will be returned.
|
|
167
|
+
|
|
168
|
+
Attachments are downloaded using S3 pre-signed URLs, with a expiry time of _one hour_. You must call `decryptWithAttachments` within this time window, or else the URL to the encrypted files will become invalid.
|
|
169
|
+
|
|
170
|
+
Attachments are end-to-end encrypted in the same way as normal form submissions, so any eavesdropper will not be able to view form attachments without your secret key.
|
|
171
|
+
|
|
172
|
+
_Warning:_ We do not have the ability to scan any attachments for malicious content (e.g. spyware or viruses), so careful handling is needed.
|
|
173
|
+
|
|
161
174
|
## Verifying Signatures Manually
|
|
162
175
|
|
|
163
176
|
You can use the following information to create a custom solution, although we recommend using this SDK.
|
package/dist/crypto.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DecryptedContent, DecryptedContentAndAttachments, DecryptParams, EncryptedFileContent } from './types';
|
|
2
2
|
export default class Crypto {
|
|
3
3
|
signingPublicKey?: string;
|
|
4
4
|
constructor({ signingPublicKey }?: {
|
|
@@ -51,4 +51,12 @@ export default class Crypto {
|
|
|
51
51
|
* @param encrypted.blob The encrypted file as a Blob object
|
|
52
52
|
*/
|
|
53
53
|
decryptFile: (formSecretKey: string, { submissionPublicKey, nonce, binary: encryptedBinary, }: EncryptedFileContent) => Promise<Uint8Array | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Decrypts an encrypted submission, and also download and decrypt any attachments alongside it.
|
|
56
|
+
* @param formSecretKey Secret key as a base-64 string
|
|
57
|
+
* @param decryptParams The params containing encrypted content and information.
|
|
58
|
+
* @returns A promise of the decrypted submission, including attachments (if any). Or else returns null if a decryption error decrypting any part of the submission.
|
|
59
|
+
* @throws {MissingPublicKeyError} if a public key is not provided when instantiating this class and is needed for verifying signed content.
|
|
60
|
+
*/
|
|
61
|
+
decryptWithAttachments: (formSecretKey: string, decryptParams: DecryptParams) => Promise<DecryptedContentAndAttachments | null>;
|
|
54
62
|
}
|
package/dist/crypto.js
CHANGED
|
@@ -39,11 +39,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
40
|
};
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
var axios_1 = __importDefault(require("axios"));
|
|
42
43
|
var tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
43
44
|
var tweetnacl_util_1 = require("tweetnacl-util");
|
|
45
|
+
var crypto_1 = require("./util/crypto");
|
|
44
46
|
var validate_1 = require("./util/validate");
|
|
45
47
|
var errors_1 = require("./errors");
|
|
46
|
-
var crypto_1 = require("./util/crypto");
|
|
47
48
|
var Crypto = /** @class */ (function () {
|
|
48
49
|
function Crypto(_a) {
|
|
49
50
|
var _this = this;
|
|
@@ -74,7 +75,7 @@ var Crypto = /** @class */ (function () {
|
|
|
74
75
|
*/
|
|
75
76
|
this.decrypt = function (formSecretKey, decryptParams) {
|
|
76
77
|
try {
|
|
77
|
-
var encryptedContent = decryptParams.encryptedContent, verifiedContent = decryptParams.verifiedContent
|
|
78
|
+
var encryptedContent = decryptParams.encryptedContent, verifiedContent = decryptParams.verifiedContent;
|
|
78
79
|
// Do not return the transformed object in `_decrypt` function as a signed
|
|
79
80
|
// object is not encoded in UTF8 and is encoded in Base-64 instead.
|
|
80
81
|
var decryptedContent = crypto_1.decryptContent(formSecretKey, encryptedContent);
|
|
@@ -171,6 +172,81 @@ var Crypto = /** @class */ (function () {
|
|
|
171
172
|
});
|
|
172
173
|
});
|
|
173
174
|
};
|
|
175
|
+
/**
|
|
176
|
+
* Decrypts an encrypted submission, and also download and decrypt any attachments alongside it.
|
|
177
|
+
* @param formSecretKey Secret key as a base-64 string
|
|
178
|
+
* @param decryptParams The params containing encrypted content and information.
|
|
179
|
+
* @returns A promise of the decrypted submission, including attachments (if any). Or else returns null if a decryption error decrypting any part of the submission.
|
|
180
|
+
* @throws {MissingPublicKeyError} if a public key is not provided when instantiating this class and is needed for verifying signed content.
|
|
181
|
+
*/
|
|
182
|
+
this.decryptWithAttachments = function (formSecretKey, decryptParams) { return __awaiter(_this, void 0, void 0, function () {
|
|
183
|
+
var decryptedRecords, filenames, attachmentRecords, decryptedContent, fieldIds, downloadPromises, _a;
|
|
184
|
+
var _this = this;
|
|
185
|
+
var _b;
|
|
186
|
+
return __generator(this, function (_c) {
|
|
187
|
+
switch (_c.label) {
|
|
188
|
+
case 0:
|
|
189
|
+
decryptedRecords = {};
|
|
190
|
+
filenames = {};
|
|
191
|
+
attachmentRecords = (_b = decryptParams.attachmentDownloadUrls) !== null && _b !== void 0 ? _b : {};
|
|
192
|
+
decryptedContent = this.decrypt(formSecretKey, decryptParams);
|
|
193
|
+
if (decryptedContent === null)
|
|
194
|
+
return [2 /*return*/, null
|
|
195
|
+
// Retrieve all original filenames for attachments for easy lookup
|
|
196
|
+
];
|
|
197
|
+
// Retrieve all original filenames for attachments for easy lookup
|
|
198
|
+
decryptedContent.responses.forEach(function (response) {
|
|
199
|
+
if (response.fieldType === 'attachment' && response.answer) {
|
|
200
|
+
filenames[response._id] = response.answer;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
fieldIds = Object.keys(attachmentRecords);
|
|
204
|
+
// Check if all fieldIds are within filenames
|
|
205
|
+
if (!crypto_1.areAttachmentFieldIdsValid(fieldIds, filenames)) {
|
|
206
|
+
return [2 /*return*/, null];
|
|
207
|
+
}
|
|
208
|
+
downloadPromises = fieldIds.map(function (fieldId) {
|
|
209
|
+
return (axios_1.default
|
|
210
|
+
// Retrieve all the attachments as JSON
|
|
211
|
+
.get(attachmentRecords[fieldId], {
|
|
212
|
+
responseType: 'json',
|
|
213
|
+
})
|
|
214
|
+
// Decrypt all the attachments
|
|
215
|
+
.then(function (_a) {
|
|
216
|
+
var downloadResponse = _a.data;
|
|
217
|
+
var encryptedFile = crypto_1.convertEncryptedAttachmentToFileContent(downloadResponse);
|
|
218
|
+
return _this.decryptFile(formSecretKey, encryptedFile);
|
|
219
|
+
})
|
|
220
|
+
.then(function (decryptedFile) {
|
|
221
|
+
// Check if the file exists and set the filename accordingly; otherwise, throw an error
|
|
222
|
+
if (decryptedFile) {
|
|
223
|
+
decryptedRecords[fieldId] = {
|
|
224
|
+
filename: filenames[fieldId],
|
|
225
|
+
content: decryptedFile,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
throw new errors_1.AttachmentDecryptionError();
|
|
230
|
+
}
|
|
231
|
+
}));
|
|
232
|
+
});
|
|
233
|
+
_c.label = 1;
|
|
234
|
+
case 1:
|
|
235
|
+
_c.trys.push([1, 3, , 4]);
|
|
236
|
+
return [4 /*yield*/, Promise.all(downloadPromises)];
|
|
237
|
+
case 2:
|
|
238
|
+
_c.sent();
|
|
239
|
+
return [3 /*break*/, 4];
|
|
240
|
+
case 3:
|
|
241
|
+
_a = _c.sent();
|
|
242
|
+
return [2 /*return*/, null];
|
|
243
|
+
case 4: return [2 /*return*/, {
|
|
244
|
+
content: decryptedContent,
|
|
245
|
+
attachments: decryptedRecords,
|
|
246
|
+
}];
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}); };
|
|
174
250
|
this.signingPublicKey = signingPublicKey;
|
|
175
251
|
}
|
|
176
252
|
return Crypto;
|
package/dist/errors.d.ts
CHANGED
|
@@ -7,4 +7,7 @@ declare class MissingPublicKeyError extends Error {
|
|
|
7
7
|
declare class WebhookAuthenticateError extends Error {
|
|
8
8
|
constructor(message: string);
|
|
9
9
|
}
|
|
10
|
-
|
|
10
|
+
declare class AttachmentDecryptionError extends Error {
|
|
11
|
+
constructor(message?: string);
|
|
12
|
+
}
|
|
13
|
+
export { MissingSecretKeyError, MissingPublicKeyError, WebhookAuthenticateError, AttachmentDecryptionError, };
|
package/dist/errors.js
CHANGED
|
@@ -54,3 +54,14 @@ var WebhookAuthenticateError = /** @class */ (function (_super) {
|
|
|
54
54
|
return WebhookAuthenticateError;
|
|
55
55
|
}(Error));
|
|
56
56
|
exports.WebhookAuthenticateError = WebhookAuthenticateError;
|
|
57
|
+
var AttachmentDecryptionError = /** @class */ (function (_super) {
|
|
58
|
+
__extends(AttachmentDecryptionError, _super);
|
|
59
|
+
function AttachmentDecryptionError(message) {
|
|
60
|
+
if (message === void 0) { message = 'Attachment decryption with the given nonce failed.'; }
|
|
61
|
+
var _this = _super.call(this, message) || this;
|
|
62
|
+
_this.name = _this.constructor.name;
|
|
63
|
+
return _this;
|
|
64
|
+
}
|
|
65
|
+
return AttachmentDecryptionError;
|
|
66
|
+
}(Error));
|
|
67
|
+
exports.AttachmentDecryptionError = AttachmentDecryptionError;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import Crypto from './crypto';
|
|
1
2
|
import { PackageInitParams } from './types';
|
|
2
3
|
import Verification from './verification';
|
|
3
4
|
import Webhooks from './webhooks';
|
|
4
|
-
import Crypto from './crypto';
|
|
5
5
|
declare const _default: (config?: PackageInitParams) => {
|
|
6
6
|
webhooks: Webhooks;
|
|
7
7
|
crypto: Crypto;
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
var publicKey_1 = require("./util/publicKey");
|
|
6
|
+
var crypto_1 = __importDefault(require("./crypto"));
|
|
6
7
|
var verification_1 = __importDefault(require("./verification"));
|
|
7
8
|
var webhooks_1 = __importDefault(require("./webhooks"));
|
|
8
|
-
var crypto_1 = __importDefault(require("./crypto"));
|
|
9
9
|
module.exports = function (config) {
|
|
10
10
|
if (config === void 0) { config = {}; }
|
|
11
11
|
var webhookSecretKey = config.webhookSecretKey, mode = config.mode, verificationOptions = config.verificationOptions;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// keys generated using nacl.sign.keyPair() from tweetnacl
|
|
3
4
|
exports.SIGNING_KEYS = {
|
|
4
5
|
staging: {
|
|
5
6
|
// staging must never contain secret keys
|
|
6
7
|
publicKey: 'rjv41kYqZwcbe3r6ymMEEKQ+Vd+DPuogN+Gzq3lP2Og=',
|
|
7
8
|
},
|
|
8
9
|
development: {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
publicKey: 'Tl5gfszlKcQj99/0uafLwVpT6JAu4C0dHGvLq1cHzFE=',
|
|
11
|
+
secretKey: 'HDBXpu+2/gu10bLHpy8HjpN89xbA6boH9GwibPGJA8BOXmB+zOUpxCP33/S5p8vBWlPokC7gLR0ca8urVwfMUQ==',
|
|
11
12
|
},
|
|
12
13
|
production: {
|
|
13
14
|
// production must never contain secret keys
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// keys generated using nacl.sign.keyPair() from tweetnacl
|
|
3
4
|
exports.VERIFICATION_KEYS = {
|
|
4
5
|
staging: {
|
|
5
6
|
// staging must never contain secret keys
|
|
6
7
|
publicKey: 'bDgK1223JbrDNePFIrj7b0z02Z5nSiBzkRYRqDdVPfA=',
|
|
7
8
|
},
|
|
8
9
|
development: {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
publicKey: 'SZ4pV0JXgj8dhFU69uHllqYcxTtliYmi+d6Ml56lnQU=',
|
|
11
|
+
secretKey: 'iGkfOuI6uxrlfw+7CZFFUZBwk86I+pu6v+g7EWA6qJpJnilXQleCPx2EVTr24eWWphzFO2WJiaL53oyXnqWdBQ==',
|
|
11
12
|
},
|
|
12
13
|
production: {
|
|
13
14
|
// production must never contain secret keys
|
package/dist/types.d.ts
CHANGED
|
@@ -21,20 +21,38 @@ export declare type FormField = {
|
|
|
21
21
|
answerArray: string[] | string[][];
|
|
22
22
|
});
|
|
23
23
|
export declare type EncryptedContent = string;
|
|
24
|
+
export declare type EncryptedAttachmentRecords = Record<string, string>;
|
|
24
25
|
export interface DecryptParams {
|
|
25
26
|
encryptedContent: EncryptedContent;
|
|
26
27
|
version: number;
|
|
27
28
|
verifiedContent?: EncryptedContent;
|
|
29
|
+
attachmentDownloadUrls?: EncryptedAttachmentRecords;
|
|
28
30
|
}
|
|
29
31
|
export declare type DecryptedContent = {
|
|
30
32
|
responses: FormField[];
|
|
31
33
|
verified?: Record<string, any>;
|
|
32
34
|
};
|
|
35
|
+
export declare type DecryptedFile = {
|
|
36
|
+
filename: string;
|
|
37
|
+
content: Uint8Array;
|
|
38
|
+
};
|
|
39
|
+
export declare type DecryptedAttachments = Record<string, DecryptedFile>;
|
|
40
|
+
export declare type DecryptedContentAndAttachments = {
|
|
41
|
+
content: DecryptedContent;
|
|
42
|
+
attachments: DecryptedAttachments;
|
|
43
|
+
};
|
|
33
44
|
export declare type EncryptedFileContent = {
|
|
34
45
|
submissionPublicKey: string;
|
|
35
46
|
nonce: string;
|
|
36
47
|
binary: Uint8Array;
|
|
37
48
|
};
|
|
49
|
+
export declare type EncryptedAttachmentContent = {
|
|
50
|
+
encryptedFile: {
|
|
51
|
+
submissionPublicKey: string;
|
|
52
|
+
nonce: string;
|
|
53
|
+
binary: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
38
56
|
export declare type Keypair = {
|
|
39
57
|
publicKey: string;
|
|
40
58
|
secretKey: string;
|
package/dist/util/crypto.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Keypair } from '../types';
|
|
1
|
+
import { Keypair, EncryptedAttachmentContent, EncryptedFileContent } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Helper method to generate a new keypair for encryption.
|
|
4
4
|
* @returns The generated keypair.
|
|
@@ -27,3 +27,16 @@ export declare const decryptContent: (formPrivateKey: string, encryptedContent:
|
|
|
27
27
|
* @throws {Error} if the message cannot be verified
|
|
28
28
|
*/
|
|
29
29
|
export declare const verifySignedMessage: (msg: Uint8Array, publicKey: string) => Record<string, any>;
|
|
30
|
+
/**
|
|
31
|
+
* Helper method to check if all the field IDs given are within the filenames
|
|
32
|
+
* @param fieldIds the list of fieldIds to check
|
|
33
|
+
* @param filenames the filenames that should contain the fields
|
|
34
|
+
* @returns boolean indicating whether the fields are valid
|
|
35
|
+
*/
|
|
36
|
+
export declare const areAttachmentFieldIdsValid: (fieldIds: string[], filenames: Record<string, string>) => boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Converts an encrypted attachment to encrypted file content
|
|
39
|
+
* @param encryptedAttachment The encrypted attachment
|
|
40
|
+
* @returns EncryptedFileContent The encrypted file content
|
|
41
|
+
*/
|
|
42
|
+
export declare const convertEncryptedAttachmentToFileContent: (encryptedAttachment: EncryptedAttachmentContent) => EncryptedFileContent;
|
package/dist/util/crypto.js
CHANGED
|
@@ -3,8 +3,8 @@ 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
|
-
var tweetnacl_util_1 = require("tweetnacl-util");
|
|
7
6
|
var tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
7
|
+
var tweetnacl_util_1 = require("tweetnacl-util");
|
|
8
8
|
/**
|
|
9
9
|
* Helper method to generate a new keypair for encryption.
|
|
10
10
|
* @returns The generated keypair.
|
|
@@ -58,3 +58,22 @@ exports.verifySignedMessage = function (msg, publicKey) {
|
|
|
58
58
|
throw new Error('Failed to open signed message with given public key');
|
|
59
59
|
return JSON.parse(tweetnacl_util_1.encodeUTF8(openedMessage));
|
|
60
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Helper method to check if all the field IDs given are within the filenames
|
|
63
|
+
* @param fieldIds the list of fieldIds to check
|
|
64
|
+
* @param filenames the filenames that should contain the fields
|
|
65
|
+
* @returns boolean indicating whether the fields are valid
|
|
66
|
+
*/
|
|
67
|
+
exports.areAttachmentFieldIdsValid = function (fieldIds, filenames) {
|
|
68
|
+
return fieldIds.every(function (fieldId) { return filenames[fieldId]; });
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Converts an encrypted attachment to encrypted file content
|
|
72
|
+
* @param encryptedAttachment The encrypted attachment
|
|
73
|
+
* @returns EncryptedFileContent The encrypted file content
|
|
74
|
+
*/
|
|
75
|
+
exports.convertEncryptedAttachmentToFileContent = function (encryptedAttachment) { return ({
|
|
76
|
+
submissionPublicKey: encryptedAttachment.encryptedFile.submissionPublicKey,
|
|
77
|
+
nonce: encryptedAttachment.encryptedFile.nonce,
|
|
78
|
+
binary: tweetnacl_util_1.decodeBase64(encryptedAttachment.encryptedFile.binary),
|
|
79
|
+
}); };
|
package/dist/util/publicKey.js
CHANGED
|
@@ -14,6 +14,7 @@ var stage_1 = __importDefault(require("./stage"));
|
|
|
14
14
|
function getSigningPublicKey(mode) {
|
|
15
15
|
switch (mode) {
|
|
16
16
|
case stage_1.default.development:
|
|
17
|
+
return signing_keys_1.SIGNING_KEYS.development.publicKey;
|
|
17
18
|
case stage_1.default.staging:
|
|
18
19
|
return signing_keys_1.SIGNING_KEYS.staging.publicKey;
|
|
19
20
|
case stage_1.default.test:
|
|
@@ -31,6 +32,7 @@ exports.getSigningPublicKey = getSigningPublicKey;
|
|
|
31
32
|
function getVerificationPublicKey(mode) {
|
|
32
33
|
switch (mode) {
|
|
33
34
|
case stage_1.default.development:
|
|
35
|
+
return verification_keys_1.VERIFICATION_KEYS.development.publicKey;
|
|
34
36
|
case stage_1.default.staging:
|
|
35
37
|
return verification_keys_1.VERIFICATION_KEYS.staging.publicKey;
|
|
36
38
|
case stage_1.default.test:
|
package/dist/util/validate.js
CHANGED
|
@@ -14,7 +14,9 @@ function determineIsFormFields(tbd) {
|
|
|
14
14
|
internal.isHeader) &&
|
|
15
15
|
internal._id &&
|
|
16
16
|
internal.fieldType &&
|
|
17
|
-
|
|
17
|
+
// The field is still valid even when the question title is empty string
|
|
18
|
+
// (even though it is not intended behavior).
|
|
19
|
+
typeof internal.question === 'string';
|
|
18
20
|
});
|
|
19
21
|
return filter.length === tbd.length;
|
|
20
22
|
}
|
package/dist/util/webhooks.js
CHANGED
|
@@ -8,8 +8,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
8
8
|
};
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
var url = __importStar(require("url"));
|
|
11
|
-
var signature_1 = require("./signature");
|
|
12
11
|
var errors_1 = require("../errors");
|
|
12
|
+
var signature_1 = require("./signature");
|
|
13
13
|
/**
|
|
14
14
|
* Helper function to construct the basestring and verify the signature of an
|
|
15
15
|
* incoming request
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VerificationAuthenticateOptions, VerificationOptions, VerificationSignatureOptions } from '../types';
|
|
2
2
|
export default class Verification {
|
|
3
3
|
verificationPublicKey?: string;
|
|
4
4
|
verificationSecretKey?: string;
|
package/dist/webhooks.js
CHANGED
|
@@ -8,8 +8,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
8
8
|
};
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
var url = __importStar(require("url"));
|
|
11
|
-
var signature_1 = require("./util/signature");
|
|
12
11
|
var parser_1 = require("./util/parser");
|
|
12
|
+
var signature_1 = require("./util/signature");
|
|
13
13
|
var webhooks_1 = require("./util/webhooks");
|
|
14
14
|
var errors_1 = require("./errors");
|
|
15
15
|
var Webhooks = /** @class */ (function () {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengovsg/formsg-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/opengovsg/formsg-javascript-sdk.git"
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"test": "jest",
|
|
13
|
-
"test-ci": "jest --coverage
|
|
14
|
-
"test
|
|
13
|
+
"test-ci": "jest --coverage",
|
|
14
|
+
"test-watch": "jest --watch",
|
|
15
15
|
"build": "tsc",
|
|
16
|
-
"prepare": "npm run build"
|
|
16
|
+
"prepare": "npm run build",
|
|
17
|
+
"version": "auto-changelog -p && git add CHANGELOG.md"
|
|
17
18
|
},
|
|
18
19
|
"keywords": [
|
|
19
20
|
"formsg",
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
"author": "Open Government Products (FormSG)",
|
|
24
25
|
"license": "MIT",
|
|
25
26
|
"dependencies": {
|
|
27
|
+
"axios": "^0.24.0",
|
|
26
28
|
"tweetnacl": "^1.0.3",
|
|
27
29
|
"tweetnacl-util": "^0.15.1"
|
|
28
30
|
},
|
|
@@ -30,11 +32,20 @@
|
|
|
30
32
|
"@babel/cli": "^7.8.4",
|
|
31
33
|
"@babel/core": "^7.9.0",
|
|
32
34
|
"@babel/preset-env": "^7.9.0",
|
|
33
|
-
"@types/jest": "^
|
|
35
|
+
"@types/jest": "^27.0.3",
|
|
34
36
|
"@types/node": "^13.11.1",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^4.25.0",
|
|
38
|
+
"auto-changelog": "^2.4.0",
|
|
39
|
+
"coveralls": "^3.1.1",
|
|
40
|
+
"eslint-config-prettier": "^8.3.0",
|
|
41
|
+
"eslint-plugin-import": "^2.23.3",
|
|
42
|
+
"eslint-plugin-jest": "^24.3.6",
|
|
43
|
+
"eslint-plugin-prettier": "^3.4.0",
|
|
44
|
+
"eslint-plugin-simple-import-sort": "^7.0.0",
|
|
45
|
+
"eslint-plugin-typesafe": "^0.5.2",
|
|
46
|
+
"jest": "^27.3.1",
|
|
47
|
+
"jest-mock-axios": "^4.4.0",
|
|
48
|
+
"ts-jest": "^27.0.7",
|
|
38
49
|
"typescript": "^3.8.3"
|
|
39
50
|
}
|
|
40
51
|
}
|