Skip to content

Commit e9407a0

Browse files
authored
feat: add default user to rafiki admin (#1493)
* Add default user to rafiki admin * change password
1 parent 8b99acf commit e9407a0

4 files changed

Lines changed: 143 additions & 1 deletion

File tree

docker/dev/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ services:
5757
WM_THRESHOLD: 100000000
5858
DEBT_THRESHOLD: 5
5959
REDIS_URL: redis://redis:6379/0
60+
KRATOS_ADMIN_URL: 'http://kratos:4434/admin'
6061
restart: always
6162
networks:
6263
- testnet

packages/wallet/backend/src/createContainer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { generateKnex } from '@/config/knex'
5151
import { asClassSingletonWithLogger, RedisClient } from '@shared/backend'
5252
import { generateLogger } from '@/config/logger'
5353
import { GraphQLClient } from 'graphql-request'
54+
import { KratosService } from './rafiki/kratos.service'
5455

5556
export interface Cradle {
5657
env: Env
@@ -92,6 +93,7 @@ export interface Cradle {
9293
grantController: GrantController
9394
walletAddressController: WalletAddressController
9495
walletAddressKeyController: WalletAddressKeyController
96+
kratosService: KratosService
9597
}
9698

9799
export async function createContainer(
@@ -147,7 +149,8 @@ export async function createContainer(
147149
quoteController: asClass(QuoteController).singleton(),
148150
grantController: asClass(GrantController).singleton(),
149151
walletAddressController: asClass(WalletAddressController).singleton(),
150-
walletAddressKeyController: asClass(WalletAddressKeyController).singleton()
152+
walletAddressKeyController: asClass(WalletAddressKeyController).singleton(),
153+
kratosService: asClassSingletonWithLogger(KratosService, logger)
151154
})
152155

153156
return container
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import axios from 'axios'
2+
import process from 'process'
3+
import { Logger } from 'winston'
4+
export class KratosService {
5+
private KRATOS_INSTANCE: string | undefined
6+
7+
constructor(private logger: Logger) {
8+
this.KRATOS_INSTANCE = process.env.KRATOS_ADMIN_URL
9+
if (!this.KRATOS_INSTANCE) {
10+
logger.error('No Kratos instance found.')
11+
}
12+
}
13+
14+
private getIdentityId = async (userEmail: string) => {
15+
try {
16+
const response = await axios.get(
17+
`${this.KRATOS_INSTANCE}/identities?credentials_identifier=${userEmail}`
18+
)
19+
if (response.data.length > 0 && response.data[0].id) {
20+
this.logger.debug(
21+
`User with email ${userEmail} exists on the system with the ID: ${response.data[0].id}`
22+
)
23+
return response.data[0].id
24+
}
25+
this.logger.debug(`No user with email ${userEmail} exists on the system`)
26+
return null
27+
} catch (error) {
28+
if (axios.isAxiosError(error)) {
29+
this.logger.error(
30+
`Error retrieving identity ${userEmail}:`,
31+
error.response?.status,
32+
error.response?.data
33+
)
34+
} else {
35+
this.logger.error(
36+
`An unexpected error occurred while trying to retrieve the identity for ${userEmail}:`,
37+
error
38+
)
39+
}
40+
}
41+
}
42+
43+
private createIdentity = async (userEmail: string) => {
44+
try {
45+
const response = await axios.post(
46+
`${this.KRATOS_INSTANCE}/identities`,
47+
{
48+
schema_id: 'default',
49+
traits: {
50+
email: userEmail
51+
},
52+
verifiable_addresses: [
53+
{
54+
value: userEmail,
55+
verified: true,
56+
via: 'email',
57+
status: 'completed'
58+
}
59+
],
60+
credentials: {
61+
password: {
62+
config: {
63+
password: '123456'
64+
}
65+
}
66+
}
67+
},
68+
{
69+
headers: {
70+
'Content-Type': 'application/json'
71+
}
72+
}
73+
)
74+
this.logger.debug(
75+
`Successfully created user ${userEmail} with ID ${response.data.id}`
76+
)
77+
return response.data.id
78+
} catch (error) {
79+
if (axios.isAxiosError(error)) {
80+
this.logger.error(
81+
`Error creating identity for ${userEmail}:`,
82+
error.response?.status,
83+
error.response?.data
84+
)
85+
} else {
86+
this.logger.error(
87+
`An unexpected error occurred while trying to create an identity for ${userEmail}:`,
88+
error
89+
)
90+
}
91+
}
92+
}
93+
94+
private createRecoveryLink = async (
95+
identityId: string,
96+
userEmail: string
97+
) => {
98+
try {
99+
const response = await axios.post(
100+
`${this.KRATOS_INSTANCE}/recovery/link`,
101+
{
102+
expires_in: '12h',
103+
identity_id: identityId
104+
},
105+
{
106+
headers: {
107+
'Content-Type': 'application/json'
108+
}
109+
}
110+
)
111+
return response.data.recovery_link
112+
} catch (error) {
113+
if (axios.isAxiosError(error)) {
114+
this.logger.error(
115+
`Error creating password for ${userEmail}:\n status:${error.response?.status}\nresponse:${error.response?.data}`
116+
)
117+
} else {
118+
this.logger.error(
119+
`An unexpected error occurred while trying to create an account recovery link for ${userEmail}:`,
120+
error
121+
)
122+
}
123+
}
124+
}
125+
126+
public run = async (userEmail: string) => {
127+
let identityId = await this.getIdentityId(userEmail)
128+
const event = identityId === null ? 'Registration' : 'Recovery'
129+
if (event === 'Registration') {
130+
identityId = await this.createIdentity(userEmail)
131+
}
132+
const recoveryLink = await this.createRecoveryLink(identityId, userEmail)
133+
this.logger.info(`${event} Link for ${userEmail}: ${recoveryLink}`)
134+
}
135+
}

packages/wallet/backend/src/user/service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getRandomValues } from 'crypto'
99
import { RafikiClient } from '@/rafiki/rafiki-client'
1010
import { WalletAddressKeyService } from '@/walletAddressKeys/service'
1111
import { BadRequest, Conflict } from '@shared/backend'
12+
import { KratosService } from '@/rafiki/kratos.service'
1213

1314
interface CreateUserArgs {
1415
email: string
@@ -32,6 +33,7 @@ export class UserService implements IUserService {
3233
private walletAddressService: WalletAddressService,
3334
private walletAddressKeyService: WalletAddressKeyService,
3435
private rafikiClient: RafikiClient,
36+
private kratosService: KratosService,
3537
private logger: Logger,
3638
private env: Env
3739
) {}
@@ -174,6 +176,7 @@ export class UserService implements IUserService {
174176
})
175177
}
176178

179+
await this.kratosService.run(this.env.DEFAULT_WALLET_ACCOUNT.email)
177180
this.logger.info('Default users have been successfully created')
178181
}
179182

0 commit comments

Comments
 (0)