@bdking71/spsignature 1.0.5 → 1.2.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/README.md +182 -45
- package/lib/OtpService.d.ts +24 -0
- package/lib/OtpService.js +93 -0
- package/lib/ProvisioningService.d.ts +50 -1
- package/lib/ProvisioningService.js +84 -26
- package/lib/TransactionSigner.d.ts +109 -2
- package/lib/TransactionSigner.js +437 -75
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/package.json +34 -16
- package/lib/VerificationService.d.ts +0 -16
- package/lib/VerificationService.js +0 -36
|
@@ -1,24 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file SecureAuditSignature.ts
|
|
3
|
+
*
|
|
4
|
+
* Provides a secure, auditable digital-signature workflow for SharePoint
|
|
5
|
+
* web parts. The module renders a modal dialog that supports:
|
|
6
|
+
*
|
|
7
|
+
* • Drawing a signature on an HTML canvas
|
|
8
|
+
* • Uploading a signature image (PNG / JPG, ≤ 5 MB)
|
|
9
|
+
* • Re-using a previously cached (LZW-compressed) signature from
|
|
10
|
+
* localStorage
|
|
11
|
+
* • Optional two-factor authentication via a 5-digit passcode
|
|
12
|
+
* dispatched through email or Microsoft Teams
|
|
13
|
+
*
|
|
14
|
+
* After the user signs, the module hashes the audit envelope
|
|
15
|
+
* (payload + signer + timestamp) with SHA-256 so that the record can
|
|
16
|
+
* later be verified without exposing the original payload.
|
|
17
|
+
*
|
|
18
|
+
* @module SecureAuditSignature
|
|
19
|
+
*/
|
|
1
20
|
import { WebPartContext } from "@microsoft/sp-webpart-base";
|
|
2
|
-
import { DeliveryChannel } from "./
|
|
21
|
+
import { DeliveryChannel } from "./OtpService";
|
|
22
|
+
/**
|
|
23
|
+
* Describes everything the caller must (or may) supply when requesting a
|
|
24
|
+
* signed audit record.
|
|
25
|
+
*/
|
|
3
26
|
export interface SignerContext {
|
|
27
|
+
/** SharePoint list-item ID that the signature relates to. */
|
|
4
28
|
itemID: number;
|
|
29
|
+
/** Display name or email of the person signing. */
|
|
5
30
|
signer: string;
|
|
31
|
+
/** Arbitrary key/value data to include in the audit envelope. */
|
|
6
32
|
payload: Record<string, unknown>;
|
|
33
|
+
/** SPFx web-part context – required for PnPjs / Graph calls. */
|
|
7
34
|
spContext: WebPartContext;
|
|
35
|
+
/** How to deliver the two-factor passcode (`"email"` | `"teams"`). */
|
|
8
36
|
channel?: DeliveryChannel;
|
|
37
|
+
/**
|
|
38
|
+
* Whether two-factor authentication is required.
|
|
39
|
+
* Defaults to `true` when omitted or set to `undefined`.
|
|
40
|
+
*/
|
|
9
41
|
requireTFA?: boolean;
|
|
10
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* The record that is ultimately persisted to SharePoint after a
|
|
45
|
+
* successful signing ceremony.
|
|
46
|
+
*/
|
|
11
47
|
export interface SharePointAuditRecord {
|
|
48
|
+
/** SHA-256 hex digest of the canonical audit envelope. */
|
|
12
49
|
signatureHash: string;
|
|
50
|
+
/** LZW-compressed data-URI of the signature image. */
|
|
13
51
|
signatureData: string;
|
|
52
|
+
/** ISO-8601 timestamp captured at the moment of signing. */
|
|
14
53
|
signatureTimestamp: string;
|
|
54
|
+
/** ID of the verification list-item (if two-factor was used). */
|
|
15
55
|
verificationItemId: number;
|
|
16
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* The canonical shape that is hashed to produce `signatureHash`.
|
|
59
|
+
* The payload keys are sorted alphabetically so that hash
|
|
60
|
+
* verification is order-independent.
|
|
61
|
+
*/
|
|
17
62
|
export interface AuditEnvelopeRecord {
|
|
18
63
|
payload: Record<string, unknown>;
|
|
19
64
|
signer: string;
|
|
20
65
|
timestamp: string;
|
|
21
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Opens a full-screen modal dialog that walks the user through:
|
|
69
|
+
*
|
|
70
|
+
* 1. (Optional) Two-factor passcode verification
|
|
71
|
+
* 2. Providing a digital signature (cached / drawn / uploaded)
|
|
72
|
+
* 3. Generating a tamper-evident SHA-256 audit record
|
|
73
|
+
*
|
|
74
|
+
* The returned promise resolves with a `SharePointAuditRecord` on
|
|
75
|
+
* success or `undefined` if the user cancels.
|
|
76
|
+
*
|
|
77
|
+
* @param context - Signer metadata and SPFx context.
|
|
78
|
+
* @param modalTitle - Title shown in the modal header.
|
|
79
|
+
* @param warningMessage - Instructional HTML rendered above the
|
|
80
|
+
* signature area.
|
|
81
|
+
* @returns A promise that resolves to the audit record or `undefined`.
|
|
82
|
+
*
|
|
83
|
+
* @throws {Error} If `context.spContext` is falsy.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const record = await promptAndGenerateSecureAudit({
|
|
88
|
+
* itemID: 42,
|
|
89
|
+
* signer: currentUser.email,
|
|
90
|
+
* payload: { amount: 1500, vendor: "Contoso" },
|
|
91
|
+
* spContext: this.context,
|
|
92
|
+
* channel: "email",
|
|
93
|
+
* requireTFA: true,
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
22
97
|
export declare function promptAndGenerateSecureAudit(context: SignerContext, modalTitle?: string, warningMessage?: string): Promise<SharePointAuditRecord | undefined>;
|
|
98
|
+
/**
|
|
99
|
+
* Decompresses an LZW-compressed signature string back into its
|
|
100
|
+
* original `data:image/…` data-URI for display in reports or
|
|
101
|
+
* print views.
|
|
102
|
+
*
|
|
103
|
+
* @param compressedSignatureData - The LZW-compressed string stored
|
|
104
|
+
* in SharePoint.
|
|
105
|
+
* @returns The original data-URI, or an empty string if
|
|
106
|
+
* decompression fails or the result is not an image
|
|
107
|
+
* data-URI.
|
|
108
|
+
*/
|
|
23
109
|
export declare function getReportableSignature(compressedSignatureData: string): string;
|
|
24
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Re-computes the SHA-256 hash of the audit envelope constructed from
|
|
112
|
+
* the supplied parameters and compares it to `storedHash`.
|
|
113
|
+
*
|
|
114
|
+
* This allows any consumer to independently verify that a signed
|
|
115
|
+
* record has not been tampered with, without needing access to the
|
|
116
|
+
* original signature image.
|
|
117
|
+
*
|
|
118
|
+
* **Note:** Only top-level payload keys are sorted. If your payload
|
|
119
|
+
* contains nested objects whose key order may vary, consider using a
|
|
120
|
+
* deep-sort utility before calling this function.
|
|
121
|
+
*
|
|
122
|
+
* @param payloadToVerify - The payload that was originally signed.
|
|
123
|
+
* @param signer - The signer identifier used at sign time.
|
|
124
|
+
* @param timestamp - The ISO-8601 timestamp captured at sign
|
|
125
|
+
* time.
|
|
126
|
+
* @param _compressedSignatureData - The compressed signature (unused by the
|
|
127
|
+
* hash, retained for API symmetry).
|
|
128
|
+
* @param storedHash - The SHA-256 hex digest to compare against.
|
|
129
|
+
* @returns `true` if the recomputed hash matches `storedHash`.
|
|
130
|
+
*/
|
|
131
|
+
export declare function verifySecureAuditRecord(payloadToVerify: Record<string, unknown>, signer: string, timestamp: string, _compressedSignatureData: string, storedHash: string): Promise<boolean>;
|