-
Notifications
You must be signed in to change notification settings - Fork 1
/
auth-provider.ts
115 lines (98 loc) · 3.23 KB
/
auth-provider.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
import { v4 as uuidv4 } from 'uuid'
import { Jwt, ProjectScopedToken, Iota } from './helpers'
import { EnvironmentUtils } from '@affinidi-tdk/common'
export interface IotaTokenOutput {
readonly iotaJwt: string
readonly iotaSessionId: string
}
export interface IAuthProviderParams {
projectId: string
tokenId: string
keyId?: string
privateKey: string
passphrase?: string
apiGatewayUrl?: string
tokenEndpoint?: string
}
export class AuthProvider {
// NOTE: publicKey to validate projectScopedToken generated by Affinidi,
// need to fetch from Affinidi service
private publicKey: string = ''
private projectScopedToken: string = ''
private readonly keyId: string
private readonly tokenId: string
private readonly passphrase: string
private readonly privateKey: string
private readonly projectId: string
private readonly apiGatewayUrl: string
private readonly tokenEndpoint: string
private readonly projectScopedTokenInstance: ProjectScopedToken
private readonly jwt: Jwt
private readonly iotaInstance: Iota
constructor(param: { [key: string]: string }) {
this.apiGatewayUrl =
param?.apiGatewayUrl ?? EnvironmentUtils.fetchApiGwUrl()
this.tokenEndpoint =
param?.tokenEndpoint ?? EnvironmentUtils.fetchElementsAuthTokenUrl()
if (!param.privateKey || !param.projectId || !param.tokenId) {
throw new Error(
'Missing parameters. Please provide privateKey, projectId and tokenId.',
)
}
this.projectId = param.projectId
this.tokenId = param.tokenId
this.keyId = param.keyId ?? param.tokenId
this.privateKey = param.privateKey
this.passphrase = param.passphrase
this.projectScopedTokenInstance = new ProjectScopedToken()
this.jwt = new Jwt()
this.iotaInstance = new Iota()
}
private async shouldRefreshToken(): Promise<boolean> {
if (!this.publicKey) {
this.publicKey = await this.jwt.fetchPublicKey(this.apiGatewayUrl)
}
const itExistsAndExpired =
!!this.projectScopedToken &&
this.jwt.validateToken(this.projectScopedToken, this.publicKey).isExpired
return !this.projectScopedToken || itExistsAndExpired
}
public async fetchProjectScopedToken(): Promise<string> {
const shouldRefreshToken = await this.shouldRefreshToken()
if (shouldRefreshToken) {
this.projectScopedToken =
await this.projectScopedTokenInstance.fetchProjectScopedToken({
apiGatewayUrl: this.apiGatewayUrl,
keyId: this.keyId,
tokenId: this.tokenId,
passphrase: this.passphrase,
privateKey: this.privateKey,
projectId: this.projectId,
audience: this.tokenEndpoint,
})
}
return this.projectScopedToken
}
public createIotaToken(
iotaConfigId: string,
did: string,
iotaSessionId?: string,
): IotaTokenOutput {
const sessionId = iotaSessionId ?? uuidv4()
return {
iotaJwt: this.iotaInstance.signIotaJwt(
this.projectId,
iotaConfigId,
sessionId,
{
keyId: this.keyId,
tokenId: `token/${this.tokenId}`,
passphrase: this.passphrase,
privateKey: this.privateKey,
audience: did,
},
),
iotaSessionId: sessionId,
}
}
}