UNPKG

@mysten/sui

Version:
1 lines 6.42 kB
{"version":3,"file":"jwt-utils.mjs","names":["i"],"sources":["../../src/zklogin/jwt-utils.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { JwtPayload } from './jwt-decode.js';\nimport { jwtDecode } from './jwt-decode.js';\nimport { normalizeZkLoginIssuer } from './utils.js';\n\nfunction base64UrlCharTo6Bits(base64UrlChar: string): number[] {\n\tif (base64UrlChar.length !== 1) {\n\t\tthrow new Error('Invalid base64Url character: ' + base64UrlChar);\n\t}\n\n\t// Define the base64URL character set\n\tconst base64UrlCharacterSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\n\n\t// Find the index of the input character in the base64URL character set\n\tconst index = base64UrlCharacterSet.indexOf(base64UrlChar);\n\n\tif (index === -1) {\n\t\tthrow new Error('Invalid base64Url character: ' + base64UrlChar);\n\t}\n\n\t// Convert the index to a 6-bit binary string\n\tconst binaryString = index.toString(2).padStart(6, '0');\n\n\t// Convert the binary string to an array of bits\n\tconst bits = Array.from(binaryString).map(Number);\n\n\treturn bits;\n}\n\nfunction base64UrlStringToBitVector(base64UrlString: string) {\n\tlet bitVector: number[] = [];\n\tfor (let i = 0; i < base64UrlString.length; i++) {\n\t\tconst base64UrlChar = base64UrlString.charAt(i);\n\t\tconst bits = base64UrlCharTo6Bits(base64UrlChar);\n\t\tbitVector = bitVector.concat(bits);\n\t}\n\treturn bitVector;\n}\n\nfunction decodeBase64URL(s: string, i: number): string {\n\tif (s.length < 2) {\n\t\tthrow new Error(`Input (s = ${s}) is not tightly packed because s.length < 2`);\n\t}\n\tlet bits = base64UrlStringToBitVector(s);\n\n\tconst firstCharOffset = i % 4;\n\tif (firstCharOffset === 0) {\n\t\t// skip\n\t} else if (firstCharOffset === 1) {\n\t\tbits = bits.slice(2);\n\t} else if (firstCharOffset === 2) {\n\t\tbits = bits.slice(4);\n\t} else {\n\t\t// (offset == 3)\n\t\tthrow new Error(`Input (s = ${s}) is not tightly packed because i%4 = 3 (i = ${i}))`);\n\t}\n\n\tconst lastCharOffset = (i + s.length - 1) % 4;\n\tif (lastCharOffset === 3) {\n\t\t// skip\n\t} else if (lastCharOffset === 2) {\n\t\tbits = bits.slice(0, bits.length - 2);\n\t} else if (lastCharOffset === 1) {\n\t\tbits = bits.slice(0, bits.length - 4);\n\t} else {\n\t\t// (offset == 0)\n\t\tthrow new Error(\n\t\t\t`Input (s = ${s}) is not tightly packed because (i + s.length - 1)%4 = 0 (i = ${i}))`,\n\t\t);\n\t}\n\n\tif (bits.length % 8 !== 0) {\n\t\tthrow new Error(`We should never reach here...`);\n\t}\n\n\tconst bytes = new Uint8Array(Math.floor(bits.length / 8));\n\tlet currentByteIndex = 0;\n\tfor (let i = 0; i < bits.length; i += 8) {\n\t\tconst bitChunk = bits.slice(i, i + 8);\n\n\t\t// Convert the 8-bit chunk to a byte and add it to the bytes array\n\t\tconst byte = parseInt(bitChunk.join(''), 2);\n\t\tbytes[currentByteIndex++] = byte;\n\t}\n\treturn new TextDecoder().decode(bytes);\n}\n\nfunction verifyExtendedClaim(claim: string) {\n\t// Last character of each extracted_claim must be '}' or ','\n\tif (!(claim.slice(-1) === '}' || claim.slice(-1) === ',')) {\n\t\tthrow new Error('Invalid claim');\n\t}\n\n\t// A hack to parse the JSON key-value pair.. but it should work\n\tconst json = JSON.parse('{' + claim.slice(0, -1) + '}');\n\tif (Object.keys(json).length !== 1) {\n\t\tthrow new Error('Invalid claim');\n\t}\n\tconst key = Object.keys(json)[0];\n\treturn [key, json[key]];\n}\n\nexport type Claim = {\n\tvalue: string;\n\tindexMod4: number;\n};\n\nexport function extractClaimValue<R>(claim: Claim, claimName: string): R {\n\tconst extendedClaim = decodeBase64URL(claim.value, claim.indexMod4);\n\tconst [name, value] = verifyExtendedClaim(extendedClaim);\n\tif (name !== claimName) {\n\t\tthrow new Error(`Invalid field name: found ${name} expected ${claimName}`);\n\t}\n\treturn value;\n}\n\nexport function decodeJwt(jwt: string): Omit<JwtPayload, 'iss' | 'aud' | 'sub'> & {\n\tiss: string;\n\taud: string;\n\tsub: string;\n\trawIss: string;\n} {\n\tconst { iss, aud, sub, ...decodedJWT } = jwtDecode(jwt);\n\n\tif (!sub || !iss || !aud) {\n\t\tthrow new Error('Missing jwt data');\n\t}\n\n\tif (Array.isArray(aud)) {\n\t\tthrow new Error('Not supported aud. Aud is an array, string was expected.');\n\t}\n\n\treturn {\n\t\t...decodedJWT,\n\t\tiss: normalizeZkLoginIssuer(iss),\n\t\trawIss: iss,\n\t\taud,\n\t\tsub,\n\t};\n}\n"],"mappings":";;;;AAOA,SAAS,qBAAqB,eAAiC;AAC9D,KAAI,cAAc,WAAW,EAC5B,OAAM,IAAI,MAAM,kCAAkC,cAAc;CAOjE,MAAM,QAHwB,mEAGM,QAAQ,cAAc;AAE1D,KAAI,UAAU,GACb,OAAM,IAAI,MAAM,kCAAkC,cAAc;CAIjE,MAAM,eAAe,MAAM,SAAS,EAAE,CAAC,SAAS,GAAG,IAAI;AAKvD,QAFa,MAAM,KAAK,aAAa,CAAC,IAAI,OAAO;;AAKlD,SAAS,2BAA2B,iBAAyB;CAC5D,IAAI,YAAsB,EAAE;AAC5B,MAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;EAEhD,MAAM,OAAO,qBADS,gBAAgB,OAAO,EAAE,CACC;AAChD,cAAY,UAAU,OAAO,KAAK;;AAEnC,QAAO;;AAGR,SAAS,gBAAgB,GAAW,GAAmB;AACtD,KAAI,EAAE,SAAS,EACd,OAAM,IAAI,MAAM,cAAc,EAAE,8CAA8C;CAE/E,IAAI,OAAO,2BAA2B,EAAE;CAExC,MAAM,kBAAkB,IAAI;AAC5B,KAAI,oBAAoB,GAAG,YAEhB,oBAAoB,EAC9B,QAAO,KAAK,MAAM,EAAE;UACV,oBAAoB,EAC9B,QAAO,KAAK,MAAM,EAAE;KAGpB,OAAM,IAAI,MAAM,cAAc,EAAE,+CAA+C,EAAE,IAAI;CAGtF,MAAM,kBAAkB,IAAI,EAAE,SAAS,KAAK;AAC5C,KAAI,mBAAmB,GAAG,YAEf,mBAAmB,EAC7B,QAAO,KAAK,MAAM,GAAG,KAAK,SAAS,EAAE;UAC3B,mBAAmB,EAC7B,QAAO,KAAK,MAAM,GAAG,KAAK,SAAS,EAAE;KAGrC,OAAM,IAAI,MACT,cAAc,EAAE,gEAAgE,EAAE,IAClF;AAGF,KAAI,KAAK,SAAS,MAAM,EACvB,OAAM,IAAI,MAAM,gCAAgC;CAGjD,MAAM,QAAQ,IAAI,WAAW,KAAK,MAAM,KAAK,SAAS,EAAE,CAAC;CACzD,IAAI,mBAAmB;AACvB,MAAK,IAAIA,MAAI,GAAGA,MAAI,KAAK,QAAQ,OAAK,GAAG;EACxC,MAAM,WAAW,KAAK,MAAMA,KAAGA,MAAI,EAAE;EAGrC,MAAM,OAAO,SAAS,SAAS,KAAK,GAAG,EAAE,EAAE;AAC3C,QAAM,sBAAsB;;AAE7B,QAAO,IAAI,aAAa,CAAC,OAAO,MAAM;;AAGvC,SAAS,oBAAoB,OAAe;AAE3C,KAAI,EAAE,MAAM,MAAM,GAAG,KAAK,OAAO,MAAM,MAAM,GAAG,KAAK,KACpD,OAAM,IAAI,MAAM,gBAAgB;CAIjC,MAAM,OAAO,KAAK,MAAM,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI;AACvD,KAAI,OAAO,KAAK,KAAK,CAAC,WAAW,EAChC,OAAM,IAAI,MAAM,gBAAgB;CAEjC,MAAM,MAAM,OAAO,KAAK,KAAK,CAAC;AAC9B,QAAO,CAAC,KAAK,KAAK,KAAK;;AAQxB,SAAgB,kBAAqB,OAAc,WAAsB;CAExE,MAAM,CAAC,MAAM,SAAS,oBADA,gBAAgB,MAAM,OAAO,MAAM,UAAU,CACX;AACxD,KAAI,SAAS,UACZ,OAAM,IAAI,MAAM,6BAA6B,KAAK,YAAY,YAAY;AAE3E,QAAO;;AAGR,SAAgB,UAAU,KAKxB;CACD,MAAM,EAAE,KAAK,KAAK,KAAK,GAAG,eAAe,UAAU,IAAI;AAEvD,KAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IACpB,OAAM,IAAI,MAAM,mBAAmB;AAGpC,KAAI,MAAM,QAAQ,IAAI,CACrB,OAAM,IAAI,MAAM,2DAA2D;AAG5E,QAAO;EACN,GAAG;EACH,KAAK,uBAAuB,IAAI;EAChC,QAAQ;EACR;EACA;EACA"}