forked from panva/oauth4webapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdpop.test.ts
86 lines (76 loc) · 2.38 KB
/
dpop.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import anyTest, { type TestFn } from 'ava'
import * as crypto from 'crypto'
import setup, { type Context, teardown } from './_setup.js'
import * as jose from 'jose'
import * as lib from '../src/index.js'
const test = anyTest as TestFn<Context>
test.before(setup)
test.after(teardown)
test('dpop()', async (t) => {
const sign = await lib.generateKeyPair('ES256')
const publicJwk = await jose.exportJWK(sign.publicKey)
t.context.mock
.get('https://rs.example.com')
.intercept({
path: '/resource?foo',
method: 'GET',
headers: {
authorization: 'DPoP token',
dpop(dpop) {
const { jwk, ...protectedHeader } = jose.decodeProtectedHeader(dpop)
const { iat, jti, ath, ...claims } = jose.decodeJwt(dpop)
t.deepEqual(protectedHeader, { alg: 'ES256', typ: 'dpop+jwt' })
t.deepEqual(jwk, publicJwk)
t.deepEqual(claims, { htu: 'https://rs.example.com/resource', htm: 'GET' })
t.is(typeof iat, 'number')
t.is(typeof jti, 'string')
t.is(ath, crypto.createHash('sha256').update('token').digest('base64url'))
return true
},
},
})
.reply(200, '')
const url = new URL('https://rs.example.com/resource?foo#bar')
const response = await lib.protectedResourceRequest('token', 'GET', url, new Headers(), null, {
DPoP: sign,
})
t.true(response instanceof Response)
})
test('dpop() w/ a nonce', async (t) => {
const sign = await lib.generateKeyPair('ES256')
t.context.mock
.get('https://rs2.example.com')
.intercept({
path: '/resource?foo',
method: 'GET',
headers: {
dpop(dpop) {
const { nonce } = jose.decodeJwt(dpop)
t.is(nonce, undefined)
return true
},
},
})
.reply(401, '', { headers: { 'DPoP-Nonce': 'foo' } })
const url = new URL('https://rs2.example.com/resource?foo#bar')
await lib.protectedResourceRequest('token', 'GET', url, new Headers(), null, {
DPoP: sign,
})
t.context.mock
.get('https://rs2.example.com')
.intercept({
path: '/resource?foo',
method: 'GET',
headers: {
dpop(dpop) {
const { nonce } = jose.decodeJwt(dpop)
t.is(nonce, 'foo')
return true
},
},
})
.reply(200, '')
await lib.protectedResourceRequest('token', 'GET', url, new Headers(), null, {
DPoP: sign,
})
})