@zerodev/permissions 5.3.2-alpha-0 → 5.3.2-alpha-1
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/_cjs/constants.js +2 -3
- package/_cjs/constants.js.map +1 -1
- package/_cjs/deserializePermissionAccount.js.map +1 -1
- package/_cjs/policies/callPolicyUtils.js +8 -24
- package/_cjs/policies/callPolicyUtils.js.map +1 -1
- package/_cjs/policies/toCallPolicy.js +2 -1
- package/_cjs/policies/toCallPolicy.js.map +1 -1
- package/_cjs/policies/types.js +0 -1
- package/_cjs/policies/types.js.map +1 -1
- package/_cjs/signers/index.js +3 -3
- package/_cjs/signers/index.js.map +1 -1
- package/_cjs/signers/toWebAuthnSigner.js +60 -74
- package/_cjs/signers/toWebAuthnSigner.js.map +1 -1
- package/_esm/constants.js +1 -8
- package/_esm/constants.js.map +1 -1
- package/_esm/deserializePermissionAccount.js.map +1 -1
- package/_esm/policies/callPolicyUtils.js +8 -24
- package/_esm/policies/callPolicyUtils.js.map +1 -1
- package/_esm/policies/toCallPolicy.js +2 -1
- package/_esm/policies/toCallPolicy.js.map +1 -1
- package/_esm/policies/types.js +0 -1
- package/_esm/policies/types.js.map +1 -1
- package/_esm/signers/index.js +1 -1
- package/_esm/signers/index.js.map +1 -1
- package/_esm/signers/toWebAuthnSigner.js +72 -88
- package/_esm/signers/toWebAuthnSigner.js.map +1 -1
- package/_types/constants.d.ts +1 -8
- package/_types/constants.d.ts.map +1 -1
- package/_types/deserializePermissionAccount.d.ts.map +1 -1
- package/_types/policies/callPolicyUtils.d.ts +1 -1
- package/_types/policies/callPolicyUtils.d.ts.map +1 -1
- package/_types/policies/toCallPolicy.d.ts.map +1 -1
- package/_types/policies/types.d.ts +6 -12
- package/_types/policies/types.d.ts.map +1 -1
- package/_types/signers/index.d.ts +1 -1
- package/_types/signers/index.d.ts.map +1 -1
- package/_types/signers/toWebAuthnSigner.d.ts +2 -3
- package/_types/signers/toWebAuthnSigner.d.ts.map +1 -1
- package/_types/types.d.ts +1 -1
- package/_types/types.d.ts.map +1 -1
- package/constants.ts +1 -10
- package/deserializePermissionAccount.ts +4 -1
- package/package.json +2 -1
- package/policies/callPolicyUtils.ts +16 -32
- package/policies/toCallPolicy.ts +2 -1
- package/policies/types.ts +17 -31
- package/signers/index.ts +1 -1
- package/signers/toWebAuthnSigner.ts +99 -115
- package/types.ts +1 -1
- package/_cjs/signers/toWebAuthnKey.js +0 -101
- package/_cjs/signers/toWebAuthnKey.js.map +0 -1
- package/_cjs/signers/webAuthnUtils.js +0 -45
- package/_cjs/signers/webAuthnUtils.js.map +0 -1
- package/_esm/signers/toWebAuthnKey.js +0 -110
- package/_esm/signers/toWebAuthnKey.js.map +0 -1
- package/_esm/signers/webAuthnUtils.js +0 -41
- package/_esm/signers/webAuthnUtils.js.map +0 -1
- package/_types/signers/toWebAuthnKey.d.ts +0 -17
- package/_types/signers/toWebAuthnKey.d.ts.map +0 -1
- package/_types/signers/webAuthnUtils.d.ts +0 -13
- package/_types/signers/webAuthnUtils.d.ts.map +0 -1
- package/signers/toWebAuthnKey.ts +0 -163
- package/signers/webAuthnUtils.ts +0 -54
package/signers/toWebAuthnKey.ts
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { Buffer } from "buffer"
|
|
2
|
-
import { type Hex, keccak256 } from "viem"
|
|
3
|
-
import { b64ToBytes, uint8ArrayToHexString } from "./webAuthnUtils.js"
|
|
4
|
-
|
|
5
|
-
export enum WebAuthnMode {
|
|
6
|
-
Register = "register",
|
|
7
|
-
Login = "login"
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type WebAuthnKey = {
|
|
11
|
-
pubX: bigint
|
|
12
|
-
pubY: bigint
|
|
13
|
-
authenticatorIdHash: Hex
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const toWebAuthnKey = async ({
|
|
17
|
-
passkeyName,
|
|
18
|
-
passkeyServerUrl,
|
|
19
|
-
webAuthnKey,
|
|
20
|
-
mode = WebAuthnMode.Login
|
|
21
|
-
}: {
|
|
22
|
-
passkeyName: string
|
|
23
|
-
passkeyServerUrl: string
|
|
24
|
-
webAuthnKey?: WebAuthnKey
|
|
25
|
-
mode: WebAuthnMode
|
|
26
|
-
}): Promise<WebAuthnKey> => {
|
|
27
|
-
if (webAuthnKey) {
|
|
28
|
-
return webAuthnKey
|
|
29
|
-
}
|
|
30
|
-
let pubKey: string | undefined
|
|
31
|
-
let authenticatorIdHash: Hex
|
|
32
|
-
if (mode === WebAuthnMode.Login) {
|
|
33
|
-
// Get login options
|
|
34
|
-
const loginOptionsResponse = await fetch(
|
|
35
|
-
`${passkeyServerUrl}/login/options`,
|
|
36
|
-
{
|
|
37
|
-
method: "POST",
|
|
38
|
-
headers: { "Content-Type": "application/json" },
|
|
39
|
-
credentials: "include"
|
|
40
|
-
}
|
|
41
|
-
)
|
|
42
|
-
const loginOptions = await loginOptionsResponse.json()
|
|
43
|
-
|
|
44
|
-
// Start authentication (login)
|
|
45
|
-
const { startAuthentication } = await import("@simplewebauthn/browser")
|
|
46
|
-
const loginCred = await startAuthentication(loginOptions)
|
|
47
|
-
|
|
48
|
-
// get authenticatorIdHash
|
|
49
|
-
authenticatorIdHash = keccak256(
|
|
50
|
-
uint8ArrayToHexString(b64ToBytes(loginCred.id))
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
// Verify authentication
|
|
54
|
-
const loginVerifyResponse = await fetch(
|
|
55
|
-
`${passkeyServerUrl}/login/verify`,
|
|
56
|
-
{
|
|
57
|
-
method: "POST",
|
|
58
|
-
headers: { "Content-Type": "application/json" },
|
|
59
|
-
body: JSON.stringify({ cred: loginCred }),
|
|
60
|
-
credentials: "include"
|
|
61
|
-
}
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
const loginVerifyResult = await loginVerifyResponse.json()
|
|
65
|
-
|
|
66
|
-
if (window.sessionStorage === undefined) {
|
|
67
|
-
throw new Error("sessionStorage is not available")
|
|
68
|
-
}
|
|
69
|
-
sessionStorage.setItem("userId", loginVerifyResult.userId)
|
|
70
|
-
|
|
71
|
-
if (!loginVerifyResult.verification.verified) {
|
|
72
|
-
throw new Error("Login not verified")
|
|
73
|
-
}
|
|
74
|
-
// Import the key
|
|
75
|
-
pubKey = loginVerifyResult.pubkey // Uint8Array pubkey
|
|
76
|
-
} else {
|
|
77
|
-
if (!passkeyName) {
|
|
78
|
-
throw new Error("No passkey name provided")
|
|
79
|
-
}
|
|
80
|
-
// Get registration options
|
|
81
|
-
const registerOptionsResponse = await fetch(
|
|
82
|
-
`${passkeyServerUrl}/register/options`,
|
|
83
|
-
{
|
|
84
|
-
method: "POST",
|
|
85
|
-
headers: {
|
|
86
|
-
"Content-Type": "application/json"
|
|
87
|
-
},
|
|
88
|
-
body: JSON.stringify({ username: passkeyName }),
|
|
89
|
-
credentials: "include"
|
|
90
|
-
}
|
|
91
|
-
)
|
|
92
|
-
const registerOptions = await registerOptionsResponse.json()
|
|
93
|
-
|
|
94
|
-
// save userId to sessionStorage
|
|
95
|
-
if (window.sessionStorage === undefined) {
|
|
96
|
-
throw new Error("sessionStorage is not available")
|
|
97
|
-
}
|
|
98
|
-
sessionStorage.setItem("userId", registerOptions.userId)
|
|
99
|
-
|
|
100
|
-
// Start registration
|
|
101
|
-
const { startRegistration } = await import("@simplewebauthn/browser")
|
|
102
|
-
const registerCred = await startRegistration(registerOptions.options)
|
|
103
|
-
|
|
104
|
-
// get authenticatorIdHash
|
|
105
|
-
authenticatorIdHash = keccak256(
|
|
106
|
-
uint8ArrayToHexString(b64ToBytes(registerCred.id))
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
// Verify registration
|
|
110
|
-
const registerVerifyResponse = await fetch(
|
|
111
|
-
`${passkeyServerUrl}/register/verify`,
|
|
112
|
-
{
|
|
113
|
-
method: "POST",
|
|
114
|
-
headers: {
|
|
115
|
-
"Content-Type": "application/json"
|
|
116
|
-
},
|
|
117
|
-
body: JSON.stringify({
|
|
118
|
-
userId: registerOptions.userId,
|
|
119
|
-
username: passkeyName,
|
|
120
|
-
cred: registerCred
|
|
121
|
-
}),
|
|
122
|
-
credentials: "include"
|
|
123
|
-
}
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
const registerVerifyResult = await registerVerifyResponse.json()
|
|
127
|
-
if (!registerVerifyResult.verified) {
|
|
128
|
-
throw new Error("Registration not verified")
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Import the key
|
|
132
|
-
pubKey = registerCred.response.publicKey
|
|
133
|
-
}
|
|
134
|
-
if (!pubKey) {
|
|
135
|
-
throw new Error("No public key returned from registration credential")
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const spkiDer = Buffer.from(pubKey, "base64")
|
|
139
|
-
const key = await crypto.subtle.importKey(
|
|
140
|
-
"spki",
|
|
141
|
-
spkiDer,
|
|
142
|
-
{
|
|
143
|
-
name: "ECDSA",
|
|
144
|
-
namedCurve: "P-256"
|
|
145
|
-
},
|
|
146
|
-
true,
|
|
147
|
-
["verify"]
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
// Export the key to the raw format
|
|
151
|
-
const rawKey = await crypto.subtle.exportKey("raw", key)
|
|
152
|
-
const rawKeyBuffer = Buffer.from(rawKey)
|
|
153
|
-
|
|
154
|
-
// The first byte is 0x04 (uncompressed), followed by x and y coordinates (32 bytes each for P-256)
|
|
155
|
-
const pubKeyX = rawKeyBuffer.subarray(1, 33).toString("hex")
|
|
156
|
-
const pubKeyY = rawKeyBuffer.subarray(33).toString("hex")
|
|
157
|
-
|
|
158
|
-
return {
|
|
159
|
-
pubX: BigInt(`0x${pubKeyX}`),
|
|
160
|
-
pubY: BigInt(`0x${pubKeyY}`),
|
|
161
|
-
authenticatorIdHash
|
|
162
|
-
}
|
|
163
|
-
}
|
package/signers/webAuthnUtils.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { p256 } from "@noble/curves/p256"
|
|
2
|
-
import { type Hex, bytesToBigInt, hexToBytes } from "viem"
|
|
3
|
-
|
|
4
|
-
const RIP7212_SUPPORTED_NETWORKS = [80001]
|
|
5
|
-
|
|
6
|
-
export const uint8ArrayToHexString = (array: Uint8Array): `0x${string}` => {
|
|
7
|
-
return `0x${Array.from(array, (byte) =>
|
|
8
|
-
byte.toString(16).padStart(2, "0")
|
|
9
|
-
).join("")}` as `0x${string}`
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const b64ToBytes = (base64: string): Uint8Array => {
|
|
13
|
-
const paddedBase64 = base64
|
|
14
|
-
.replace(/-/g, "+")
|
|
15
|
-
.replace(/_/g, "/")
|
|
16
|
-
.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), "=")
|
|
17
|
-
const binString = atob(paddedBase64)
|
|
18
|
-
return Uint8Array.from(binString, (m) => m.codePointAt(0) ?? 0)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const findQuoteIndices = (
|
|
22
|
-
input: string
|
|
23
|
-
): { beforeType: bigint; beforeChallenge: bigint } => {
|
|
24
|
-
const beforeTypeIndex = BigInt(input.lastIndexOf('"type":"webauthn.get"'))
|
|
25
|
-
const beforeChallengeIndex = BigInt(input.indexOf('"challenge'))
|
|
26
|
-
return {
|
|
27
|
-
beforeType: beforeTypeIndex,
|
|
28
|
-
beforeChallenge: beforeChallengeIndex
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Parse DER-encoded P256-SHA256 signature to contract-friendly signature
|
|
33
|
-
// and normalize it so the signature is not malleable.
|
|
34
|
-
export function parseAndNormalizeSig(derSig: Hex): { r: bigint; s: bigint } {
|
|
35
|
-
const parsedSignature = p256.Signature.fromDER(derSig.slice(2))
|
|
36
|
-
const bSig = hexToBytes(`0x${parsedSignature.toCompactHex()}`)
|
|
37
|
-
// assert(bSig.length === 64, "signature is not 64 bytes");
|
|
38
|
-
const bR = bSig.slice(0, 32)
|
|
39
|
-
const bS = bSig.slice(32)
|
|
40
|
-
|
|
41
|
-
// Avoid malleability. Ensure low S (<= N/2 where N is the curve order)
|
|
42
|
-
const r = bytesToBigInt(bR)
|
|
43
|
-
let s = bytesToBigInt(bS)
|
|
44
|
-
const n = BigInt(
|
|
45
|
-
"0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"
|
|
46
|
-
)
|
|
47
|
-
if (s > n / 2n) {
|
|
48
|
-
s = n - s
|
|
49
|
-
}
|
|
50
|
-
return { r, s }
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export const isRIP7212SupportedNetwork = (chainId: number): boolean =>
|
|
54
|
-
RIP7212_SUPPORTED_NETWORKS.includes(chainId)
|