@@ -3,7 +3,7 @@ import { configDotenv } from "dotenv";
3
3
4
4
configDotenv ( ) ;
5
5
6
- type AccountCreationResponseData = {
6
+ type ResponseData = {
7
7
captchaBypassToken ?: string ;
8
8
message ?: string | "The model state is invalid." ;
9
9
validationErrors ?: {
@@ -12,12 +12,20 @@ type AccountCreationResponseData = {
12
12
exceptionMessage ?: string | null ;
13
13
exceptionStackTrace ?: string | null ;
14
14
innerExceptionMessage ?: string | null ;
15
- object ?: "register " | "error" ;
15
+ object ?: "registerFinish " | "error" ;
16
16
} ;
17
17
18
+ type PreAccountCreateResponseData = ResponseData | string ;
19
+
20
+ type AccountCreationResponseData = ResponseData ;
21
+
18
22
let failedAttemptsCount = 0 ;
19
23
20
24
async function createAccount ( ) {
25
+ if ( failedAttemptsCount > 60 ) {
26
+ throw new Error ( "The account was unable to be created." ) ;
27
+ }
28
+
21
29
const {
22
30
GENERATED_RSA_KEY_PAIR_PROTECTED_PRIVATE_KEY ,
23
31
GENERATED_RSA_KEY_PAIR_PUBLIC_KEY ,
@@ -31,30 +39,81 @@ async function createAccount() {
31
39
const vaultHost = `${ VAULT_HOST_URL } :${ VAULT_HOST_PORT } ` ;
32
40
33
41
try {
34
- const response = await fetch ( ` ${ vaultHost } /identity/accounts/register` , {
42
+ const requestOptions = {
35
43
headers : {
36
- "Content-Type" : "application/json" ,
44
+ accept : "application/json" ,
45
+ "content-type" : "application/json; charset=utf-8" ,
37
46
} ,
38
- body : JSON . stringify ( {
39
- email : `${ VAULT_EMAIL } ` ,
40
- name : null ,
41
- masterPasswordHash : `${ MASTER_PASSWORD_HASH } ` ,
42
- key : `${ PROTECTED_SYMMETRIC_KEY } ` ,
43
- kdf : 0 ,
44
- kdfIterations : `${ KDF_ITERATIONS } ` ,
45
- referenceData : { id : null } ,
46
- captchaResponse : null ,
47
- masterPasswordHint : null ,
48
- keys : {
49
- publicKey : `${ GENERATED_RSA_KEY_PAIR_PUBLIC_KEY } ` ,
50
- encryptedPrivateKey : `${ GENERATED_RSA_KEY_PAIR_PROTECTED_PRIVATE_KEY } ` ,
51
- } ,
52
- } ) ,
53
47
method : "POST" ,
54
- } ) ;
48
+ } ;
49
+
50
+ const preCreationResponse = await fetch (
51
+ `${ vaultHost } /identity/accounts/register/send-verification-email` ,
52
+ {
53
+ ...requestOptions ,
54
+ body : JSON . stringify ( { email : `${ VAULT_EMAIL } ` , name : "" } ) ,
55
+ } ,
56
+ ) ;
57
+
58
+ const preCreationResponseData =
59
+ ( await preCreationResponse . json ( ) ) as PreAccountCreateResponseData ;
60
+
61
+ if (
62
+ typeof preCreationResponseData !== "string" &&
63
+ preCreationResponseData . object === "error"
64
+ ) {
65
+ const emailIsTaken = ! ! preCreationResponseData . message . match (
66
+ / ^ E m a i l .+ @ .+ i s a l r e a d y t a k e n $ / g,
67
+ ) ?. length ;
68
+
69
+ if ( emailIsTaken ) {
70
+ emitSuccessMessage ( vaultHost ) ;
71
+ return ;
72
+ }
73
+
74
+ console . log ( `Retrying account creation at ${ vaultHost } ...` ) ;
75
+ failedAttemptsCount ++ ;
76
+ setTimeout ( createAccount , 3000 ) ;
77
+ return ;
78
+ } else if (
79
+ typeof preCreationResponseData !== "string" ||
80
+ ! preCreationResponseData . startsWith (
81
+ "BwRegistrationEmailVerificationToken_" ,
82
+ )
83
+ ) {
84
+ console . log (
85
+ "Unexpected response: expected BwRegistrationEmailVerificationToken" ,
86
+ ) ;
87
+ return ;
88
+ }
89
+
90
+ const response = await fetch (
91
+ `${ vaultHost } /identity/accounts/register/finish` ,
92
+ {
93
+ ...requestOptions ,
94
+ body : JSON . stringify ( {
95
+ email : `${ VAULT_EMAIL } ` ,
96
+ emailVerificationToken : preCreationResponseData ,
97
+ masterPasswordHash : `${ MASTER_PASSWORD_HASH } ` ,
98
+ kdf : 0 ,
99
+ kdfIterations : KDF_ITERATIONS ,
100
+ masterPasswordHint : "" ,
101
+ userSymmetricKey : `${ PROTECTED_SYMMETRIC_KEY } ` ,
102
+ userAsymmetricKeys : {
103
+ publicKey : `${ GENERATED_RSA_KEY_PAIR_PUBLIC_KEY } ` ,
104
+ encryptedPrivateKey : `${ GENERATED_RSA_KEY_PAIR_PROTECTED_PRIVATE_KEY } ` ,
105
+ } ,
106
+ } ) ,
107
+ } ,
108
+ ) ;
55
109
56
110
const responseData = ( await response . json ( ) ) as AccountCreationResponseData ;
57
111
112
+ if ( responseData . object === "registerFinish" ) {
113
+ emitSuccessMessage ( vaultHost ) ;
114
+ return ;
115
+ }
116
+
58
117
let emailIsTaken = false ;
59
118
60
119
const responseErrors =
@@ -70,25 +129,24 @@ async function createAccount() {
70
129
}
71
130
72
131
if ( emailIsTaken ) {
73
- console . log (
74
- "\x1b[1m\x1b[32m%s\x1b[0m" , // bold, light green foreground
75
- `Account has been created successfully at ${ vaultHost } !\n` ,
76
- ) ;
132
+ emitSuccessMessage ( vaultHost ) ;
77
133
78
134
return ;
79
135
}
80
136
} catch ( error ) {
81
137
// Server isn't ready yet
82
138
}
83
139
84
- if ( failedAttemptsCount > 60 ) {
85
- throw new Error ( "The account was unable to be created." ) ;
86
- }
87
-
88
140
console . log ( `Retrying account creation at ${ vaultHost } ...` ) ;
89
-
90
141
failedAttemptsCount ++ ;
91
142
setTimeout ( createAccount , 3000 ) ;
92
143
}
93
144
145
+ function emitSuccessMessage ( vaultHost : string ) {
146
+ console . log (
147
+ "\x1b[1m\x1b[32m%s\x1b[0m" , // bold, light green foreground
148
+ `Account has been created successfully at ${ vaultHost } !\n` ,
149
+ ) ;
150
+ }
151
+
94
152
createAccount ( ) ;
0 commit comments