instasign 1.0.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/CHANGELOG.md +17 -0
- package/README.md +122 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +24 -0
- package/dist/resources/Envelopes.d.ts +58 -0
- package/dist/resources/Envelopes.js +69 -0
- package/dist/resources/SignRequests.d.ts +24 -0
- package/dist/resources/SignRequests.js +27 -0
- package/dist/resources/Webhooks.d.ts +8 -0
- package/dist/resources/Webhooks.js +32 -0
- package/package.json +39 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.0] - 2026-02-27
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Initial release of the `instasign-api-sdk`.
|
|
9
|
+
- **Stripe-inspired API**: High-quality, resource-based orientation (`instasign.envelopes.create()`).
|
|
10
|
+
- **Extended Envelopes API**: Added `get`, `updateMetadata`, `addSignRequest`, `addSignRequests`, and `removeSignRequest`.
|
|
11
|
+
- **SignRequests API Improvements**: Added `getFile` to retrieve file metadata from a request ID.
|
|
12
|
+
- **Enhanced Configuration**: Added support for both `apiKey` (Dashboard API) and `restApiKey` (Parse REST API).
|
|
13
|
+
- **Webhook Support**: Dedicated `Webhooks` class with `constructEvent` for secure signature verification.
|
|
14
|
+
- **Strict Typing**: Integrated `schema.d.ts` generated from OpenAPI specification for 100% type safety.
|
|
15
|
+
- **Deep Type Inference**: Improved Swagger generator to extract nested properties for cloud function results.
|
|
16
|
+
- **Configurable Tolerance**: Webhook signature verification now supports a configurable `webhookTolerance` (defaulting to 300s).
|
|
17
|
+
- **Public API Filtering**: Automatically excludes internal/sensitive cloud functions (e.g., `createApiKey`, `db-migrate`) from the SDK surface.
|
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Instasign Node.js SDK
|
|
2
|
+
|
|
3
|
+
The **Instasign Node.js SDK** provides convenient access to the **Instasign Service** from applications written in server-side JavaScript or TypeScript. It is designed to simplify document signing workflows by providing a high-level, promise-based API for creating envelopes, managing sign requests, and verifying webhooks.
|
|
4
|
+
|
|
5
|
+
> [!CAUTION]
|
|
6
|
+
> **Security Warning:** While this library can technically be used in client-side (frontend) applications, it is **strongly discouraged** for security reasons. Using the SDK on the frontend requires you to expose your Instasign API key, which could be stolen by anyone visiting your site. For production applications, always perform Instasign API calls from a secure server-side environment.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
Install the package with:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install instasign-api-sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
The package needs to be configured with your account's API key.
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { Instasign } from 'instasign-api-sdk';
|
|
22
|
+
|
|
23
|
+
const instasign = new Instasign({
|
|
24
|
+
apiKey: 'your_api_key',
|
|
25
|
+
restApiKey: 'your_parse_rest_api_key', // Optional
|
|
26
|
+
serverUrl: 'https://parseapi.back4app.com', // Optional
|
|
27
|
+
appId: 'your_app_id', // Optional
|
|
28
|
+
webhookTolerance: 300 // default is 300 seconds (5 minutes)
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Envelopes
|
|
33
|
+
|
|
34
|
+
Envelopes are containers for one or more documents that need to be signed.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// Create an envelope
|
|
38
|
+
const envelope = await instasign.envelopes.create({
|
|
39
|
+
name: 'Service Agreement',
|
|
40
|
+
description: 'Please sign the attached document',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// List envelopes
|
|
44
|
+
const envelopes = await instasign.envelopes.list();
|
|
45
|
+
|
|
46
|
+
// Retrieve an envelope by ID
|
|
47
|
+
const envelope = await instasign.envelopes.get('envelope_id_here');
|
|
48
|
+
|
|
49
|
+
// Update envelope metadata
|
|
50
|
+
await instasign.envelopes.updateMetadata({
|
|
51
|
+
envelopeId: 'envelope_id_here',
|
|
52
|
+
metadata: { customField: 'value' }
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Add a sign request to an envelope
|
|
56
|
+
await instasign.envelopes.addSignRequest({
|
|
57
|
+
envelopeId: 'envelope_id_here',
|
|
58
|
+
filename: 'contract.pdf',
|
|
59
|
+
base64File: '...'
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Delete an envelope
|
|
63
|
+
await instasign.envelopes.delete('envelope_id_here');
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Sign Requests
|
|
67
|
+
|
|
68
|
+
Manage individual signature requests.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Create a sign request
|
|
72
|
+
const signRequest = await instasign.signRequests.create({
|
|
73
|
+
filename: 'contract.pdf',
|
|
74
|
+
base64File: '...', // base64 encoded file content
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Retrieve file data
|
|
78
|
+
const fileData = await instasign.signRequests.getFile('request_id_here');
|
|
79
|
+
|
|
80
|
+
// Complete a sign request
|
|
81
|
+
await instasign.signRequests.complete({
|
|
82
|
+
requestId: 'request_id_here',
|
|
83
|
+
signedFileDataBase64: '...'
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Webhooks
|
|
88
|
+
|
|
89
|
+
Instasign can send webhook events to your server. Use the `webhooks` resource to verify signature headers securely.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const payload = req.body; // Raw request body
|
|
93
|
+
const sig = req.headers['x-instasign-signature'];
|
|
94
|
+
const endpointSecret = 'secret_key';
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const event = instasign.webhooks.constructEvent(payload, sig, endpointSecret);
|
|
98
|
+
// Handle the event
|
|
99
|
+
console.log(event.type);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
console.error(`Webhook Error: ${err.message}`);
|
|
102
|
+
res.status(400).send(`Webhook Error: ${err.message}`);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## TypeScript Support
|
|
107
|
+
|
|
108
|
+
This library is built with TypeScript and provides industry-standard type definitions auto-generated from the Instasign OpenAPI schema. Every method in the SDK is strictly typed, ensuring you catch errors at compile time and get excellent IDE autocompletion.
|
|
109
|
+
|
|
110
|
+
## Configuration Options
|
|
111
|
+
|
|
112
|
+
| Option | Type | Description |
|
|
113
|
+
| :--- | :--- | :--- |
|
|
114
|
+
| `apiKey` | `string` | **Required**. Your Instasign Dashboard API Key (passed in `x-api-key` header). |
|
|
115
|
+
| `restApiKey` | `string` | Optional. Your Parse REST API Key (passed in `X-Parse-REST-API-KEY` header). |
|
|
116
|
+
| `serverUrl` | `string` | Optional. Base URL for the Parse Server (defaults to Back4App). |
|
|
117
|
+
| `appId` | `string` | Optional. Your Parse Application ID. |
|
|
118
|
+
| `webhookTolerance` | `number` | Optional. Allowed time drift for webhook signatures in seconds (default: 300). |
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
ISC
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Envelopes } from './resources/Envelopes.js';
|
|
2
|
+
import { SignRequests } from './resources/SignRequests.js';
|
|
3
|
+
import { Webhooks } from './resources/Webhooks.js';
|
|
4
|
+
export interface IInstasignConfig {
|
|
5
|
+
apiKey: string;
|
|
6
|
+
appId?: string;
|
|
7
|
+
restApiKey?: string;
|
|
8
|
+
serverUrl?: string;
|
|
9
|
+
webhookTolerance?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class Instasign {
|
|
12
|
+
private client;
|
|
13
|
+
envelopes: Envelopes;
|
|
14
|
+
signRequests: SignRequests;
|
|
15
|
+
webhooks: Webhooks;
|
|
16
|
+
constructor(config: IInstasignConfig);
|
|
17
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { Envelopes } from './resources/Envelopes.js';
|
|
3
|
+
import { SignRequests } from './resources/SignRequests.js';
|
|
4
|
+
import { Webhooks } from './resources/Webhooks.js';
|
|
5
|
+
export class Instasign {
|
|
6
|
+
client;
|
|
7
|
+
envelopes;
|
|
8
|
+
signRequests;
|
|
9
|
+
webhooks;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.client = axios.create({
|
|
12
|
+
baseURL: config.serverUrl || 'https://parseapi.back4app.com',
|
|
13
|
+
headers: {
|
|
14
|
+
'X-Parse-APPLICATION-ID': config.appId || 'jKFo8BFQRdiAUV4F3o3SIDWLpLUb2TVW7bVl7lwH',
|
|
15
|
+
'X-Parse-REST-API-KEY': config.restApiKey || 'Gjm9pmxZh0DjXHkcFlf0kGZjHfYEY4ERw71TvLig',
|
|
16
|
+
'x-api-key': config.apiKey,
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
this.envelopes = new Envelopes(this.client);
|
|
21
|
+
this.signRequests = new SignRequests(this.client);
|
|
22
|
+
this.webhooks = new Webhooks(config.webhookTolerance ?? 300);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { paths } from '../schema.js';
|
|
3
|
+
type CreateEnvelopeParams = NonNullable<paths["/functions/createEnvelope"]["post"]["requestBody"]>["content"]["application/json"];
|
|
4
|
+
type CreateEnvelopeResponse = NonNullable<NonNullable<paths["/functions/createEnvelope"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
5
|
+
type GetEnvelopesParams = NonNullable<paths["/functions/getEnvelopes"]["post"]["requestBody"]>["content"]["application/json"];
|
|
6
|
+
type GetEnvelopesResponse = NonNullable<NonNullable<paths["/functions/getEnvelopes"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
7
|
+
type GetEnvelopeResponse = NonNullable<NonNullable<paths["/functions/getEnvelope"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
8
|
+
type CompleteEnvelopeResponse = NonNullable<NonNullable<paths["/functions/completeEnvelope"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
9
|
+
type DeleteEnvelopeResponse = NonNullable<NonNullable<paths["/functions/deleteEnvelope"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
10
|
+
type UpdateEnvelopeMetadataParams = NonNullable<paths["/functions/updateEnvelopeMetadata"]["post"]["requestBody"]>["content"]["application/json"];
|
|
11
|
+
type UpdateEnvelopeMetadataResponse = NonNullable<NonNullable<paths["/functions/updateEnvelopeMetadata"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
12
|
+
type RemoveSignRequestFromEnvelopeParams = NonNullable<paths["/functions/removeSignRequestFromEnvelope"]["post"]["requestBody"]>["content"]["application/json"];
|
|
13
|
+
type RemoveSignRequestFromEnvelopeResponse = NonNullable<NonNullable<paths["/functions/removeSignRequestFromEnvelope"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
14
|
+
type AddSignRequestToEnvelopeParams = NonNullable<paths["/functions/addSignRequestToEnvelope"]["post"]["requestBody"]>["content"]["application/json"];
|
|
15
|
+
type AddSignRequestToEnvelopeResponse = NonNullable<NonNullable<paths["/functions/addSignRequestToEnvelope"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
16
|
+
type AddSignRequestsToEnvelopeParams = AddSignRequestToEnvelopeParams[];
|
|
17
|
+
type AddSignRequestsToEnvelopeResponse = AddSignRequestToEnvelopeResponse[];
|
|
18
|
+
export declare class Envelopes {
|
|
19
|
+
private client;
|
|
20
|
+
constructor(client: AxiosInstance);
|
|
21
|
+
/**
|
|
22
|
+
* Create a new envelope
|
|
23
|
+
*/
|
|
24
|
+
create(params: CreateEnvelopeParams): Promise<CreateEnvelopeResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* List envelopes
|
|
27
|
+
*/
|
|
28
|
+
list(params?: GetEnvelopesParams): Promise<GetEnvelopesResponse>;
|
|
29
|
+
/**
|
|
30
|
+
* Retrieve envelope status
|
|
31
|
+
*/
|
|
32
|
+
get(envelopeId: string): Promise<GetEnvelopeResponse>;
|
|
33
|
+
/**
|
|
34
|
+
* Complete an envelope
|
|
35
|
+
*/
|
|
36
|
+
complete(envelopeId: string): Promise<CompleteEnvelopeResponse>;
|
|
37
|
+
/**
|
|
38
|
+
* Delete an envelope
|
|
39
|
+
*/
|
|
40
|
+
delete(envelopeId: string): Promise<DeleteEnvelopeResponse>;
|
|
41
|
+
/**
|
|
42
|
+
* Update envelope metadata
|
|
43
|
+
*/
|
|
44
|
+
updateMetadata(params: UpdateEnvelopeMetadataParams): Promise<UpdateEnvelopeMetadataResponse>;
|
|
45
|
+
/**
|
|
46
|
+
* Remove sign request from envelope
|
|
47
|
+
*/
|
|
48
|
+
removeSignRequest(params: RemoveSignRequestFromEnvelopeParams): Promise<RemoveSignRequestFromEnvelopeResponse>;
|
|
49
|
+
/**
|
|
50
|
+
* Add sign request to envelope
|
|
51
|
+
*/
|
|
52
|
+
addSignRequest(params: AddSignRequestToEnvelopeParams): Promise<AddSignRequestToEnvelopeResponse>;
|
|
53
|
+
/**
|
|
54
|
+
* Add multiple sign request to envelope
|
|
55
|
+
*/
|
|
56
|
+
addSignRequests(params: AddSignRequestsToEnvelopeParams): Promise<AddSignRequestsToEnvelopeResponse>;
|
|
57
|
+
}
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export class Envelopes {
|
|
2
|
+
client;
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Create a new envelope
|
|
8
|
+
*/
|
|
9
|
+
async create(params) {
|
|
10
|
+
const response = await this.client.post('/functions/createEnvelope', params);
|
|
11
|
+
return response.data.result;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* List envelopes
|
|
15
|
+
*/
|
|
16
|
+
async list(params = {}) {
|
|
17
|
+
const response = await this.client.post('/functions/getEnvelopes', params);
|
|
18
|
+
return response.data.result;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Retrieve envelope status
|
|
22
|
+
*/
|
|
23
|
+
async get(envelopeId) {
|
|
24
|
+
const response = await this.client.post('/functions/getEnvelope', { envelopeId });
|
|
25
|
+
return response.data.result;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Complete an envelope
|
|
29
|
+
*/
|
|
30
|
+
async complete(envelopeId) {
|
|
31
|
+
const response = await this.client.post('/functions/completeEnvelope', { envelopeId });
|
|
32
|
+
return response.data.result;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Delete an envelope
|
|
36
|
+
*/
|
|
37
|
+
async delete(envelopeId) {
|
|
38
|
+
const response = await this.client.post('/functions/deleteEnvelope', { envelopeId });
|
|
39
|
+
return response.data.result;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Update envelope metadata
|
|
43
|
+
*/
|
|
44
|
+
async updateMetadata(params) {
|
|
45
|
+
const response = await this.client.post('/functions/updateEnvelopeMetadata', params);
|
|
46
|
+
return response.data.result;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Remove sign request from envelope
|
|
50
|
+
*/
|
|
51
|
+
async removeSignRequest(params) {
|
|
52
|
+
const response = await this.client.post('/functions/removeSignRequestFromEnvelope', params);
|
|
53
|
+
return response.data.result;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Add sign request to envelope
|
|
57
|
+
*/
|
|
58
|
+
async addSignRequest(params) {
|
|
59
|
+
const response = await this.client.post('/functions/addSignRequestToEnvelope', params);
|
|
60
|
+
return response.data.result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Add multiple sign request to envelope
|
|
64
|
+
*/
|
|
65
|
+
async addSignRequests(params) {
|
|
66
|
+
const response = await this.client.post('/functions/addMultipleSignRequestsToEnvelope', params);
|
|
67
|
+
return response.data.result;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { paths } from '../schema.js';
|
|
3
|
+
type CreateSignRequestParams = NonNullable<paths["/functions/createSignRequest"]["post"]["requestBody"]>["content"]["application/json"];
|
|
4
|
+
type CreateSignRequestResponse = NonNullable<NonNullable<paths["/functions/createSignRequest"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
5
|
+
type CompleteSignRequestParams = NonNullable<paths["/functions/completeSignRequest"]["post"]["requestBody"]>["content"]["application/json"];
|
|
6
|
+
type CompleteSignRequestResponse = NonNullable<NonNullable<paths["/functions/completeSignRequest"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
7
|
+
type GetFileFromRequestIdResponse = NonNullable<NonNullable<paths["/functions/getFileFromRequestId"]["post"]["responses"]>["200"]["content"]>["application/json"]["result"];
|
|
8
|
+
export declare class SignRequests {
|
|
9
|
+
private client;
|
|
10
|
+
constructor(client: AxiosInstance);
|
|
11
|
+
/**
|
|
12
|
+
* Create a new sign request
|
|
13
|
+
*/
|
|
14
|
+
create(params: CreateSignRequestParams): Promise<CreateSignRequestResponse>;
|
|
15
|
+
/**
|
|
16
|
+
* Complete a sign request
|
|
17
|
+
*/
|
|
18
|
+
complete(params: CompleteSignRequestParams): Promise<CompleteSignRequestResponse>;
|
|
19
|
+
/**
|
|
20
|
+
* Get file from request id
|
|
21
|
+
*/
|
|
22
|
+
getFile(requestId: string): Promise<GetFileFromRequestIdResponse>;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class SignRequests {
|
|
2
|
+
client;
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Create a new sign request
|
|
8
|
+
*/
|
|
9
|
+
async create(params) {
|
|
10
|
+
const response = await this.client.post('/functions/createSignRequest', params);
|
|
11
|
+
return response.data.result;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Complete a sign request
|
|
15
|
+
*/
|
|
16
|
+
async complete(params) {
|
|
17
|
+
const response = await this.client.post('/functions/completeSignRequest', params);
|
|
18
|
+
return response.data.result;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get file from request id
|
|
22
|
+
*/
|
|
23
|
+
async getFile(requestId) {
|
|
24
|
+
const response = await this.client.post('/functions/getFileFromRequestId', { requestId });
|
|
25
|
+
return response.data.result;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
export class Webhooks {
|
|
3
|
+
tolerance;
|
|
4
|
+
constructor(tolerance = 300) {
|
|
5
|
+
this.tolerance = tolerance;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Verify and parse a webhook event
|
|
9
|
+
*/
|
|
10
|
+
constructEvent(payload, signatureHeader, webhookSecret) {
|
|
11
|
+
const parts = signatureHeader.split(',');
|
|
12
|
+
const timestamp = parts.find((p) => p.startsWith('t='))?.split('=')[1];
|
|
13
|
+
const signature = parts.find((p) => p.startsWith('v1='))?.split('=')[1];
|
|
14
|
+
if (!timestamp || !signature) {
|
|
15
|
+
throw new Error('Invalid signature header');
|
|
16
|
+
}
|
|
17
|
+
const now = Math.floor(Date.now() / 1000);
|
|
18
|
+
if (Math.abs(now - parseInt(timestamp)) > this.tolerance) {
|
|
19
|
+
throw new Error('Signature too old');
|
|
20
|
+
}
|
|
21
|
+
const signedPayload = `${timestamp}.${payload}`;
|
|
22
|
+
const expectedSignature = crypto
|
|
23
|
+
.createHmac('sha256', webhookSecret)
|
|
24
|
+
.update(signedPayload)
|
|
25
|
+
.digest('hex');
|
|
26
|
+
const isValid = crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));
|
|
27
|
+
if (!isValid) {
|
|
28
|
+
throw new Error('Invalid signature');
|
|
29
|
+
}
|
|
30
|
+
return JSON.parse(payload);
|
|
31
|
+
}
|
|
32
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "instasign",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Instasign API wrapper",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"CHANGELOG.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"instasign",
|
|
18
|
+
"digital-signature",
|
|
19
|
+
"e-signature",
|
|
20
|
+
"sdk",
|
|
21
|
+
"nodejs",
|
|
22
|
+
"typescript",
|
|
23
|
+
"document-signing"
|
|
24
|
+
],
|
|
25
|
+
"author": "Cyberneid",
|
|
26
|
+
"contributors": [
|
|
27
|
+
"Cyberneid",
|
|
28
|
+
"Ciro Carandente"
|
|
29
|
+
],
|
|
30
|
+
"license": "Apache-2.0",
|
|
31
|
+
"type": "module",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"axios": "^1.12.2"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"typescript": "^5.0.0",
|
|
37
|
+
"@types/node": "^20.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|