vestauth 0.3.2 → 0.3.3
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/package.json +2 -2
- package/src/cli/actions/provider/verify.js +5 -17
- package/src/cli/commands/primitives.js +0 -7
- package/src/cli/commands/provider.js +0 -7
- package/src/lib/helpers/agentHeaders.js +1 -11
- package/src/lib/helpers/authorityMessage.js +11 -0
- package/src/lib/helpers/edPublicKeyObject.js +7 -0
- package/src/lib/helpers/headers.js +6 -12
- package/src/lib/helpers/parseSignatureInputHeader.js +22 -0
- package/src/lib/helpers/providerVerify.js +36 -0
- package/src/lib/helpers/providerVerifyWebBotAuth.js +25 -0
- package/src/lib/helpers/stripDictionaryKey.js +7 -0
- package/src/lib/helpers/verifyAuthorizationHeader.js +1 -1
- package/src/lib/helpers/{verify.js → verifyOld.js} +2 -2
- package/src/lib/helpers/webBotAuthSignature.js +2 -7
- package/src/lib/primitives.js +2 -2
- package/src/lib/provider.js +4 -2
- package/src/cli/actions/primitives/challenge.js +0 -23
- package/src/cli/actions/provider/challenge.js +0 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vestauth",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "auth for agents–from the creator of dotenvx",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vestauth"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"commander": "^11.1.0",
|
|
44
44
|
"eciesjs": "^0.4.16",
|
|
45
45
|
"execa": "^5.1.1",
|
|
46
|
-
"
|
|
46
|
+
"structured-headers": "^2.0.2",
|
|
47
47
|
"undici": "7.11.0",
|
|
48
48
|
"web-bot-auth": "^0.1.2"
|
|
49
49
|
},
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
const { logger } = require('./../../../shared/logger')
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const { verifierFromJWK } = require('web-bot-auth/crypto')
|
|
3
|
+
const provider = require('./../../../lib/provider')
|
|
5
4
|
|
|
6
|
-
async function
|
|
5
|
+
async function verify (httpMethod, uri, signatureHeader, signatureInputHeader, publicKey) {
|
|
7
6
|
logger.debug(`httpMethod: ${httpMethod}`)
|
|
8
7
|
logger.debug(`uri: ${uri}`)
|
|
9
8
|
logger.debug(`signatureHeader: ${signatureHeader}`)
|
|
@@ -13,19 +12,8 @@ async function _verify (httpMethod, uri, signatureHeader, signatureInputHeader,
|
|
|
13
12
|
const options = this.opts()
|
|
14
13
|
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
15
14
|
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
Signature: signatureHeader,
|
|
19
|
-
'Signature-Input': signatureInputHeader
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const signedRequest = new Request(uri, { headers: headers })
|
|
23
|
-
const r = await verify(signedRequest, verifier)
|
|
24
|
-
console.log(r)
|
|
25
|
-
|
|
26
|
-
const output = {
|
|
27
|
-
implement: 'todo'
|
|
28
|
-
}
|
|
15
|
+
const output = await provider.verify(httpMethod, uri, signatureHeader, signatureInputHeader, JSON.parse(publicKey))
|
|
16
|
+
// const output = await provider.verifyWebBotAuth(httpMethod, uri, signatureHeader, signatureInputHeader, JSON.parse(publicKey))
|
|
29
17
|
|
|
30
18
|
let space = 0
|
|
31
19
|
if (options.prettyPrint) {
|
|
@@ -35,4 +23,4 @@ async function _verify (httpMethod, uri, signatureHeader, signatureInputHeader,
|
|
|
35
23
|
console.log(JSON.stringify(output, null, space))
|
|
36
24
|
}
|
|
37
25
|
|
|
38
|
-
module.exports =
|
|
26
|
+
module.exports = verify
|
|
@@ -6,13 +6,6 @@ primitives
|
|
|
6
6
|
.description('🔩 primitives')
|
|
7
7
|
.allowUnknownOption()
|
|
8
8
|
|
|
9
|
-
// vestauth primitives challenge
|
|
10
|
-
const challengeAction = require('./../actions/primitives/challenge')
|
|
11
|
-
primitives.command('challenge')
|
|
12
|
-
.description('generate challenge')
|
|
13
|
-
.option('-pp, --pretty-print', 'pretty print output')
|
|
14
|
-
.action(challengeAction)
|
|
15
|
-
|
|
16
9
|
// vestauth primitives hash [message]
|
|
17
10
|
const hashAction = require('./../actions/primitives/hash')
|
|
18
11
|
primitives.command('hash')
|
|
@@ -18,11 +18,4 @@ provider.command('verify')
|
|
|
18
18
|
.option('-pp, --pretty-print', 'pretty print output')
|
|
19
19
|
.action(verifyAction)
|
|
20
20
|
|
|
21
|
-
// vestauth provider challenge
|
|
22
|
-
const challengeAction = require('./../actions/provider/challenge')
|
|
23
|
-
provider.command('challenge')
|
|
24
|
-
.description('generate challenge')
|
|
25
|
-
.option('-pp, --pretty-print', 'pretty print output')
|
|
26
|
-
.action(challengeAction)
|
|
27
|
-
|
|
28
21
|
module.exports = provider
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const headers = require('./headers')
|
|
2
2
|
const dotenvx = require('@dotenvx/dotenvx')
|
|
3
|
-
const { verify } = require('web-bot-auth')
|
|
4
|
-
const { verifierFromJWK } = require('web-bot-auth/crypto')
|
|
5
3
|
|
|
6
4
|
async function agentHeaders (httpMethod, uri, tag = 'vestauth', nonce = null) {
|
|
7
5
|
let publicKey = null
|
|
@@ -11,15 +9,7 @@ async function agentHeaders (httpMethod, uri, tag = 'vestauth', nonce = null) {
|
|
|
11
9
|
|
|
12
10
|
if (!publicKey && !privateKey) throw new Error('missing AGENT_PUBLIC_KEY and AGENT_PRIVATE_KEY. Run [vestauth agent init]')
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// verification (temp testing)
|
|
17
|
-
const verifier = await verifierFromJWK(JSON.parse(publicKey))
|
|
18
|
-
const signedRequest = new Request(uri, { headers: _headers })
|
|
19
|
-
const r = await verify(signedRequest, verifier)
|
|
20
|
-
console.log(r)
|
|
21
|
-
|
|
22
|
-
return _headers
|
|
12
|
+
return await headers(httpMethod, uri, privateKey, tag, nonce)
|
|
23
13
|
}
|
|
24
14
|
|
|
25
15
|
module.exports = agentHeaders
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
function authorityMessage (uri, signatureParams) {
|
|
2
|
+
const u = new URL(uri)
|
|
3
|
+
const authority = u.host // includes port if present
|
|
4
|
+
|
|
5
|
+
return [
|
|
6
|
+
`"@authority": ${authority}`,
|
|
7
|
+
`"@signature-params": ${signatureParams}`
|
|
8
|
+
].join('\n')
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = authorityMessage
|
|
@@ -2,11 +2,7 @@ const thumbprint = require('./thumbprint')
|
|
|
2
2
|
const signatureParams = require('./signatureParams')
|
|
3
3
|
const webBotAuthSignature = require('./webBotAuthSignature')
|
|
4
4
|
|
|
5
|
-
// const { signatureHeaders } = require('web-bot-auth')
|
|
6
|
-
// const { signerFromJWK } = require('web-bot-auth/crypto')
|
|
7
|
-
|
|
8
5
|
async function headers (httpMethod, uri, privateKeyString, tag = 'vestauth', nonce = null) {
|
|
9
|
-
// shared
|
|
10
6
|
const privateKey = JSON.parse(privateKeyString)
|
|
11
7
|
const kid = thumbprint(privateKey)
|
|
12
8
|
privateKey.kid = kid
|
|
@@ -14,7 +10,7 @@ async function headers (httpMethod, uri, privateKeyString, tag = 'vestauth', non
|
|
|
14
10
|
// // theirs
|
|
15
11
|
// const request = new Request(uri)
|
|
16
12
|
// const now = new Date()
|
|
17
|
-
//
|
|
13
|
+
// return await signatureHeaders(
|
|
18
14
|
// request,
|
|
19
15
|
// await signerFromJWK(JSON.parse(privateKeyString)),
|
|
20
16
|
// {
|
|
@@ -24,15 +20,13 @@ async function headers (httpMethod, uri, privateKeyString, tag = 'vestauth', non
|
|
|
24
20
|
// )
|
|
25
21
|
|
|
26
22
|
// ours
|
|
27
|
-
const
|
|
28
|
-
const
|
|
23
|
+
const signatureInput = signatureParams(privateKey.kid, tag, nonce)
|
|
24
|
+
const signature = webBotAuthSignature(httpMethod, uri, signatureInput, privateKey)
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
Signature: `sig1=:${
|
|
32
|
-
'Signature-Input': `sig1=${
|
|
26
|
+
return {
|
|
27
|
+
Signature: `sig1=:${signature}:`,
|
|
28
|
+
'Signature-Input': `sig1=${signatureInput}`
|
|
33
29
|
}
|
|
34
|
-
|
|
35
|
-
return headersOurs
|
|
36
30
|
}
|
|
37
31
|
|
|
38
32
|
module.exports = headers
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const { parseDictionary } = require('structured-headers')
|
|
2
|
+
|
|
3
|
+
// example: sig1=(\"@authority\");created=1769707366;keyid=\"xWuYtVgVV_ZQcfEWexUoln9ynA56PmfF4tAvWQ_Bf_o\";alg=\"ed25519\";expires=1769707666;nonce=\"RtdaKawQVJxEAJwCfI_5-7oVTmfjFkz-rGGifYZ2o2MdAMwJF2nYG3713rL1f9FJmPp8T2j4Sqcmh8H8p8TkRA\";tag=\"web-bot-auth\"
|
|
4
|
+
function parseSignatureInputHeader (signatureInputHeader) {
|
|
5
|
+
const dictionary = parseDictionary(signatureInputHeader)
|
|
6
|
+
const entry = dictionary.entries().next()
|
|
7
|
+
const [key, innerlist] = entry.value
|
|
8
|
+
const [cwp, params] = innerlist
|
|
9
|
+
const values = Object.fromEntries(params)
|
|
10
|
+
const components = []
|
|
11
|
+
for (const entry of cwp) {
|
|
12
|
+
components.push(entry[0])
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
key,
|
|
17
|
+
values,
|
|
18
|
+
components
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = parseSignatureInputHeader
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const crypto = require('crypto')
|
|
2
|
+
|
|
3
|
+
const parseSignatureInputHeader = require('./parseSignatureInputHeader')
|
|
4
|
+
const stripDictionaryKey = require('./stripDictionaryKey')
|
|
5
|
+
const authorityMessage = require('./authorityMessage')
|
|
6
|
+
const edPublicKeyObject = require('./edPublicKeyObject')
|
|
7
|
+
const epoch = require('./epoch')
|
|
8
|
+
|
|
9
|
+
function providerVerify (httpMetod, uri, signatureHeader, signatureInputHeader, publicKey) {
|
|
10
|
+
const { values } = parseSignatureInputHeader(signatureInputHeader)
|
|
11
|
+
|
|
12
|
+
// return early false, since expired
|
|
13
|
+
if (values.expires && values.expires < epoch(new Date())) {
|
|
14
|
+
return {
|
|
15
|
+
success: false
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const signatureParams = stripDictionaryKey(signatureInputHeader)
|
|
20
|
+
const signature = stripDictionaryKey(signatureHeader)
|
|
21
|
+
const message = authorityMessage(uri, signatureParams)
|
|
22
|
+
const publicKeyObject = edPublicKeyObject(publicKey)
|
|
23
|
+
|
|
24
|
+
const success = crypto.verify(
|
|
25
|
+
null,
|
|
26
|
+
Buffer.from(message, 'utf8'),
|
|
27
|
+
publicKeyObject,
|
|
28
|
+
Buffer.from(signature, 'base64')
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
success
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = providerVerify
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { verify } = require('web-bot-auth')
|
|
2
|
+
const { verifierFromJWK } = require('web-bot-auth/crypto')
|
|
3
|
+
|
|
4
|
+
async function providerVerifyWebBotAuth (httpMetod, uri, signatureHeader, signatureInputHeader, publicKey) {
|
|
5
|
+
let success = false
|
|
6
|
+
|
|
7
|
+
const verifier = await verifierFromJWK(publicKey)
|
|
8
|
+
const signedRequest = new Request(uri, {
|
|
9
|
+
headers: {
|
|
10
|
+
Signature: signatureHeader,
|
|
11
|
+
'Signature-Input': signatureInputHeader
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
await verify(signedRequest, verifier)
|
|
17
|
+
success = true
|
|
18
|
+
} catch (_e) {}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
success
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = providerVerifyWebBotAuth
|
|
@@ -2,7 +2,7 @@ const secp = require('@noble/secp256k1')
|
|
|
2
2
|
const hash = require('./hash')
|
|
3
3
|
const stripFormatting = require('./stripFormatting')
|
|
4
4
|
|
|
5
|
-
function
|
|
5
|
+
function verifyOld (challenge, signatureBase64, publicKeyHexPossiblyFormatted) {
|
|
6
6
|
const publicKeyHex = stripFormatting(publicKeyHexPossiblyFormatted)
|
|
7
7
|
const hashChallenge = hash(challenge)
|
|
8
8
|
const signature = Buffer.from(signatureBase64, 'base64url')
|
|
@@ -11,4 +11,4 @@ function verify (challenge, signatureBase64, publicKeyHexPossiblyFormatted) {
|
|
|
11
11
|
return secp.verify(signature, hashChallenge, publicKeyBytes)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
module.exports =
|
|
14
|
+
module.exports = verifyOld
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
const crypto = require('crypto')
|
|
2
2
|
const edPrivateKeyObject = require('./edPrivateKeyObject')
|
|
3
|
+
const authorityMessage = require('./authorityMessage')
|
|
3
4
|
|
|
4
5
|
function webBotAuthSignature (method = 'GET', uri = '', signatureParams, privateKey) {
|
|
5
|
-
const
|
|
6
|
-
const authority = u.host // includes port if present
|
|
7
|
-
|
|
8
|
-
const message = [
|
|
9
|
-
`"@authority": ${authority}`,
|
|
10
|
-
`"@signature-params": ${signatureParams}`
|
|
11
|
-
].join('\n')
|
|
6
|
+
const message = authorityMessage(uri, signatureParams)
|
|
12
7
|
|
|
13
8
|
// const message = [
|
|
14
9
|
// `"@method": ${method.toUpperCase()}`,
|
package/src/lib/primitives.js
CHANGED
|
@@ -4,7 +4,7 @@ const keypair = require('./helpers/keypair')
|
|
|
4
4
|
const keypairOld = require('./helpers/keypairOld')
|
|
5
5
|
const headers = require('./helpers/headers')
|
|
6
6
|
const sign = require('./helpers/sign')
|
|
7
|
-
const
|
|
7
|
+
const verifyOld = require('./helpers/verifyOld')
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
challenge,
|
|
@@ -13,5 +13,5 @@ module.exports = {
|
|
|
13
13
|
keypairOld,
|
|
14
14
|
headers,
|
|
15
15
|
sign,
|
|
16
|
-
|
|
16
|
+
verifyOld
|
|
17
17
|
}
|
package/src/lib/provider.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
const
|
|
1
|
+
const providerVerify = require('./helpers/providerVerify')
|
|
2
|
+
const providerVerifyWebBotAuth = require('./helpers/providerVerifyWebBotAuth')
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
4
|
-
|
|
5
|
+
verify: providerVerify,
|
|
6
|
+
verifyWebBotAuth: providerVerifyWebBotAuth
|
|
5
7
|
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const { logger } = require('./../../../shared/logger')
|
|
2
|
-
|
|
3
|
-
const primitives = require('./../../../lib/primitives')
|
|
4
|
-
|
|
5
|
-
function challenge () {
|
|
6
|
-
const options = this.opts()
|
|
7
|
-
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
8
|
-
|
|
9
|
-
const chal = primitives.challenge()
|
|
10
|
-
|
|
11
|
-
const output = {
|
|
12
|
-
challenge: chal
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let space = 0
|
|
16
|
-
if (options.prettyPrint) {
|
|
17
|
-
space = 2
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
console.log(JSON.stringify(output, null, space))
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
module.exports = challenge
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const { logger } = require('./../../../shared/logger')
|
|
2
|
-
|
|
3
|
-
const prov = require('./../../../lib/provider')
|
|
4
|
-
|
|
5
|
-
async function provider (website) {
|
|
6
|
-
const options = this.opts()
|
|
7
|
-
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
8
|
-
|
|
9
|
-
const output = await prov.challenge()
|
|
10
|
-
|
|
11
|
-
let space = 0
|
|
12
|
-
if (options.prettyPrint) {
|
|
13
|
-
space = 2
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
console.log(JSON.stringify(output, null, space))
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
module.exports = provider
|