UNPKG

2.84 kBJavaScriptView Raw
1const isObject = require('../help/is_object')
2let validateCrit = require('../help/validate_crit')
3const { JWSInvalid } = require('../errors')
4
5validateCrit = validateCrit.bind(undefined, JWSInvalid)
6
7const compactSerializer = (payload, [recipient]) => {
8 return `${recipient.protected}.${payload}.${recipient.signature}`
9}
10compactSerializer.validate = (jws, { 0: { unprotectedHeader, protectedHeader }, length }) => {
11 if (length !== 1 || unprotectedHeader) {
12 throw new JWSInvalid('JWS Compact Serialization doesn\'t support multiple recipients or JWS unprotected headers')
13 }
14 validateCrit(protectedHeader, unprotectedHeader, protectedHeader ? protectedHeader.crit : undefined)
15}
16
17const flattenedSerializer = (payload, [recipient]) => {
18 const { header, signature, protected: prot } = recipient
19
20 return {
21 payload,
22 ...prot ? { protected: prot } : undefined,
23 ...header ? { header } : undefined,
24 signature
25 }
26}
27flattenedSerializer.validate = (jws, { 0: { unprotectedHeader, protectedHeader }, length }) => {
28 if (length !== 1) {
29 throw new JWSInvalid('Flattened JWS JSON Serialization doesn\'t support multiple recipients')
30 }
31 validateCrit(protectedHeader, unprotectedHeader, protectedHeader ? protectedHeader.crit : undefined)
32}
33
34const generalSerializer = (payload, recipients) => {
35 return {
36 payload,
37 signatures: recipients.map(({ header, signature, protected: prot }) => {
38 return {
39 ...prot ? { protected: prot } : undefined,
40 ...header ? { header } : undefined,
41 signature
42 }
43 })
44 }
45}
46generalSerializer.validate = (jws, recipients) => {
47 recipients.forEach(({ protectedHeader, unprotectedHeader }) => {
48 validateCrit(protectedHeader, unprotectedHeader, protectedHeader ? protectedHeader.crit : undefined)
49 })
50}
51
52const isJSON = (input) => {
53 return isObject(input) && (typeof input.payload === 'string' || Buffer.isBuffer(input.payload))
54}
55
56const isValidRecipient = (recipient) => {
57 return isObject(recipient) && typeof recipient.signature === 'string' &&
58 (recipient.header === undefined || isObject(recipient.header)) &&
59 (recipient.protected === undefined || typeof recipient.protected === 'string')
60}
61
62const isMultiRecipient = (input) => {
63 if (Array.isArray(input.signatures) && input.signatures.every(isValidRecipient)) {
64 return true
65 }
66
67 return false
68}
69
70const detect = (input) => {
71 if (typeof input === 'string' && input.split('.').length === 3) {
72 return 'compact'
73 }
74
75 if (isJSON(input)) {
76 if (isMultiRecipient(input)) {
77 return 'general'
78 }
79
80 if (isValidRecipient(input)) {
81 return 'flattened'
82 }
83 }
84
85 throw new JWSInvalid('JWS malformed or invalid serialization')
86}
87
88module.exports = {
89 compact: compactSerializer,
90 flattened: flattenedSerializer,
91 general: generalSerializer,
92 detect
93}