fakes.js
1.86 KB
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
/**
* 测试用 fake Port —— 无密码学副作用的薄替身(断言「编排走 Port」而非自研)。
* 仅测试目录引用,不进公共面。
*/
/** fake hasher:哈希=可逆前缀(仅测试,证明编排调用了 hash/verify)。 */
export function createFakeHasher() {
const calls = { hash: 0, verify: 0 }
return {
calls,
async hash(plain) {
calls.hash += 1
return `h$${plain}`
},
async verify(plain, hash) {
calls.verify += 1
return hash === `h$${plain}`
},
}
}
/** fake tokenSigner:把 claims JSON 编码为 token(含 ttl 派生 exp)。 */
export function createFakeSigner() {
return {
async sign(claims, { ttlMs }) {
const exp = Date.now() + ttlMs
return `tok.${Buffer.from(JSON.stringify({ ...claims, exp })).toString('base64url')}`
},
async verify(token) {
if (typeof token !== 'string' || !token.startsWith('tok.')) {
const e = new Error('bad token')
e.code = 'ERR_JWT_INVALID'
throw e
}
const claims = JSON.parse(Buffer.from(token.slice(4), 'base64url').toString('utf8'))
if (claims.exp && Date.now() > claims.exp) {
const e = new Error('expired')
e.code = 'ERR_JWT_EXPIRED'
throw e
}
return claims
},
}
}
/** fake oauth:按注入表返回身份,或抛错模拟验签失败。 */
export function createFakeOauth(table = {}, { throwOn } = {}) {
return {
async exchange({ provider, code }) {
if (throwOn && throwOn === code) throw new Error('verify failed')
const entry = table[`${provider}:${code}`]
if (!entry) throw new Error('unknown code')
return entry
},
}
}
/** fake email:记录投递的验证码,供断言。 */
export function createFakeEmail(sink = []) {
return {
sent: sink,
async sendCode(args) {
sink.push(args)
},
}
}