-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsiwt.ts
130 lines (116 loc) · 3.95 KB
/
siwt.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright (C) 2022, vDL Digital Ventures GmbH <[email protected]>
*
* SPDX-License-Identifier: MIT
*/
import { verifySignature as taquitoVerifySignature } from '@taquito/utils'
import jwt from 'jsonwebtoken'
import type { sign as Sign, verify as Verify } from 'jsonwebtoken'
import { AxiosInstance } from 'axios'
import { assoc, objOf, pipe, prop, always } from 'ramda'
import { match } from 'ts-pattern'
import {
AccessControlQuery,
SignInMessageData,
SignInPayload,
TokenPayload,
Network,
ConditionType,
AccessControlQueryDependencies,
} from './types'
import { constructSignPayload, generateMessageData, packMessagePayload } from './utils'
import { ACCESS_TOKEN_EXPIRATION, ID_TOKEN_EXPIRATION, REFRESH_TOKEN_EXPIRATION } from './constants'
import {
validateNFTCondition,
validateTokenBalanceCondition,
validateWhitelistCondition,
validateXTZBalanceCondition,
} from './utils/siwt.utils'
import { getBalance, getLedgerFromStorage, getTokenBalance } from './data'
import { http } from './http'
export const createMessagePayload = (signatureRequestData: SignInMessageData) =>
pipe(
generateMessageData,
packMessagePayload,
objOf('payload'),
assoc('pkh', prop('pkh')(signatureRequestData)),
constructSignPayload,
)(signatureRequestData)
export const _signIn = (http: AxiosInstance) => (baseUrl: string) => (payload: SignInPayload) =>
http({
baseURL: baseUrl,
method: 'POST',
url: '/signin',
data: payload,
})
export const signIn = _signIn(http)
export const verifySignature = taquitoVerifySignature
export const _generateIdToken =
(sign: typeof Sign) =>
({ pkh, claims = {}, userInfo = {} }: TokenPayload) =>
sign(
{
...claims,
pkh,
...userInfo,
},
process.env.ID_TOKEN_SECRET as string,
{ expiresIn: ID_TOKEN_EXPIRATION },
)
export const generateIdToken = _generateIdToken(jwt?.sign)
export const _generateAccessToken =
(sign: typeof Sign) =>
({ pkh, claims = {} }: TokenPayload) =>
sign(
{
...claims,
sub: pkh,
},
process.env.ACCESS_TOKEN_SECRET as string,
{ expiresIn: ACCESS_TOKEN_EXPIRATION },
)
export const generateAccessToken = _generateAccessToken(jwt?.sign)
export const _generateRefreshToken = (sign: typeof Sign) => (pkh: string) =>
sign({ pkh }, process.env.REFRESH_TOKEN_SECRET as string, { expiresIn: REFRESH_TOKEN_EXPIRATION })
export const generateRefreshToken = _generateRefreshToken(jwt?.sign)
export const _verifyAccessToken = (verify: typeof Verify) => (accessToken: string) => {
try {
const { sub } = verify(accessToken, process.env.ACCESS_TOKEN_SECRET as string)
return sub
} catch {
return false
}
}
export const verifyAccessToken = _verifyAccessToken(jwt?.verify)
export const _verifyRefreshToken = (verify: typeof Verify) => (refreshToken: string) =>
verify(refreshToken, process.env.REFRESH_TOKEN_SECRET as string)
export const verifyRefreshToken = _verifyRefreshToken(jwt?.verify)
export const _queryAccessControl = (deps: AccessControlQueryDependencies) => async (query: AccessControlQuery) => {
const {
network = Network.ghostnet,
parameters: { pkh },
test: { type },
} = query
const { getLedgerFromStorage, getBalance, getTokenBalance, whitelist } = deps
try {
const testResults = await match(type)
.with(ConditionType.nft, () => validateNFTCondition(getLedgerFromStorage)(query))
.with(ConditionType.xtzBalance, () => validateXTZBalanceCondition(getBalance)(query))
.with(ConditionType.tokenBalance, () => validateTokenBalanceCondition(getTokenBalance)(query))
.with(ConditionType.whitelist, () => validateWhitelistCondition(whitelist)(query))
.otherwise(always(Promise.resolve({ passed: false })))
return {
network,
pkh,
testResults,
}
} catch (error) {
return error
}
}
export const queryAccessControl = _queryAccessControl({
getLedgerFromStorage,
getBalance,
getTokenBalance,
whitelist: [],
})