Skip to content

Commit cf64fb8

Browse files
tiankiiesaugomez31
andauthored
fix: onboarding prevent cross login (#286)
* fix(onboarding): loginDeviceUpgradeWithPhone return phone already exist error * feat: user login upgrade telegram - mutation * chore: user login upgrade telegram - schemas * chore: login-telegram-upgrade format * chore: unnecessary comments removed * test(e2d|bats): user-login-upgrade-telegram mutation --------- Co-authored-by: Esaú Gómez <[email protected]>
1 parent c8e404c commit cf64fb8

File tree

17 files changed

+393
-29
lines changed

17 files changed

+393
-29
lines changed

apps/consent/app/graphql/generated.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export type Scalars = {
7272
SignedAmount: { input: number; output: number; }
7373
/** A string amount (of a currency) that can be negative (e.g. in a transaction) */
7474
SignedDisplayMajorAmount: { input: string; output: string; }
75+
/** Nonce provided by Telegram Passport to validate the login/upgrade flow */
76+
TelegramPassportNonce: { input: string; output: string; }
7577
/** Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) */
7678
Timestamp: { input: number; output: number; }
7779
/** A time-based one-time password */
@@ -1045,6 +1047,7 @@ export type Mutation = {
10451047
readonly userEmailRegistrationValidate: UserEmailRegistrationValidatePayload;
10461048
readonly userLogin: AuthTokenPayload;
10471049
readonly userLoginUpgrade: UpgradePayload;
1050+
readonly userLoginUpgradeTelegram: UpgradePayload;
10481051
readonly userLogout: SuccessPayload;
10491052
readonly userPhoneDelete: UserPhoneDeletePayload;
10501053
readonly userPhoneRegistrationInitiate: SuccessPayload;
@@ -1283,6 +1286,11 @@ export type MutationUserLoginUpgradeArgs = {
12831286
};
12841287

12851288

1289+
export type MutationUserLoginUpgradeTelegramArgs = {
1290+
input: UserLoginUpgradeTelegramInput;
1291+
};
1292+
1293+
12861294
export type MutationUserLogoutArgs = {
12871295
input?: InputMaybe<UserLogoutInput>;
12881296
};
@@ -2078,6 +2086,11 @@ export type UserLoginUpgradeInput = {
20782086
readonly phone: Scalars['Phone']['input'];
20792087
};
20802088

2089+
export type UserLoginUpgradeTelegramInput = {
2090+
readonly nonce: Scalars['TelegramPassportNonce']['input'];
2091+
readonly phone: Scalars['Phone']['input'];
2092+
};
2093+
20812094
export type UserLogoutInput = {
20822095
readonly deviceToken: Scalars['String']['input'];
20832096
};
@@ -2346,4 +2359,4 @@ export function useGetUserIdSuspenseQuery(baseOptions?: Apollo.SkipToken | Apoll
23462359
export type GetUserIdQueryHookResult = ReturnType<typeof useGetUserIdQuery>;
23472360
export type GetUserIdLazyQueryHookResult = ReturnType<typeof useGetUserIdLazyQuery>;
23482361
export type GetUserIdSuspenseQueryHookResult = ReturnType<typeof useGetUserIdSuspenseQuery>;
2349-
export type GetUserIdQueryResult = Apollo.QueryResult<GetUserIdQuery, GetUserIdQueryVariables>;
2362+
export type GetUserIdQueryResult = Apollo.QueryResult<GetUserIdQuery, GetUserIdQueryVariables>;

apps/consent/codegen.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ generates:
6565
ContactHandle: "string"
6666
ContactType: "string"
6767
ContactDisplayName: "string"
68+
TelegramPassportNonce: "string"

apps/dashboard/codegen.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,4 @@ generates:
7474
ContactHandle: "string"
7575
ContactType: "string"
7676
ContactDisplayName: "string"
77+
TelegramPassportNonce: "string"

apps/dashboard/services/graphql/generated.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ export type Scalars = {
7575
SignedAmount: { input: number; output: number; }
7676
/** A string amount (of a currency) that can be negative (e.g. in a transaction) */
7777
SignedDisplayMajorAmount: { input: string; output: string; }
78+
/** Nonce provided by Telegram Passport to validate the login/upgrade flow */
79+
TelegramPassportNonce: { input: string; output: string; }
7880
/** Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) */
7981
Timestamp: { input: number; output: number; }
8082
/** A time-based one-time password */
@@ -1143,6 +1145,7 @@ export type Mutation = {
11431145
readonly userEmailRegistrationValidate: UserEmailRegistrationValidatePayload;
11441146
readonly userLogin: AuthTokenPayload;
11451147
readonly userLoginUpgrade: UpgradePayload;
1148+
readonly userLoginUpgradeTelegram: UpgradePayload;
11461149
readonly userLogout: SuccessPayload;
11471150
readonly userPhoneDelete: UserPhoneDeletePayload;
11481151
readonly userPhoneRegistrationInitiate: SuccessPayload;
@@ -1396,6 +1399,11 @@ export type MutationUserLoginUpgradeArgs = {
13961399
};
13971400

13981401

1402+
export type MutationUserLoginUpgradeTelegramArgs = {
1403+
input: UserLoginUpgradeTelegramInput;
1404+
};
1405+
1406+
13991407
export type MutationUserLogoutArgs = {
14001408
input?: InputMaybe<UserLogoutInput>;
14011409
};
@@ -2267,6 +2275,11 @@ export type UserLoginUpgradeInput = {
22672275
readonly phone: Scalars['Phone']['input'];
22682276
};
22692277

2278+
export type UserLoginUpgradeTelegramInput = {
2279+
readonly nonce: Scalars['TelegramPassportNonce']['input'];
2280+
readonly phone: Scalars['Phone']['input'];
2281+
};
2282+
22702283
export type UserLogoutInput = {
22712284
readonly deviceToken: Scalars['String']['input'];
22722285
};
@@ -3761,6 +3774,7 @@ export type ResolversTypes = {
37613774
SupportChatMessageAddPayload: ResolverTypeWrapper<Omit<SupportChatMessageAddPayload, 'errors'> & { errors: ReadonlyArray<ResolversTypes['Error']> }>;
37623775
SupportMessage: ResolverTypeWrapper<SupportMessage>;
37633776
SupportRole: SupportRole;
3777+
TelegramPassportNonce: ResolverTypeWrapper<Scalars['TelegramPassportNonce']['output']>;
37643778
Timestamp: ResolverTypeWrapper<Scalars['Timestamp']['output']>;
37653779
TotpCode: ResolverTypeWrapper<Scalars['TotpCode']['output']>;
37663780
TotpRegistrationId: ResolverTypeWrapper<Scalars['TotpRegistrationId']['output']>;
@@ -3785,6 +3799,7 @@ export type ResolversTypes = {
37853799
UserEmailRegistrationValidatePayload: ResolverTypeWrapper<Omit<UserEmailRegistrationValidatePayload, 'errors' | 'me'> & { errors: ReadonlyArray<ResolversTypes['Error']>, me?: Maybe<ResolversTypes['User']> }>;
37863800
UserLoginInput: UserLoginInput;
37873801
UserLoginUpgradeInput: UserLoginUpgradeInput;
3802+
UserLoginUpgradeTelegramInput: UserLoginUpgradeTelegramInput;
37883803
UserLogoutInput: UserLogoutInput;
37893804
UserPhoneDeletePayload: ResolverTypeWrapper<Omit<UserPhoneDeletePayload, 'errors' | 'me'> & { errors: ReadonlyArray<ResolversTypes['Error']>, me?: Maybe<ResolversTypes['User']> }>;
37903805
UserPhoneRegistrationInitiateInput: UserPhoneRegistrationInitiateInput;
@@ -3988,6 +4003,7 @@ export type ResolversParentTypes = {
39884003
SupportChatMessageAddInput: SupportChatMessageAddInput;
39894004
SupportChatMessageAddPayload: Omit<SupportChatMessageAddPayload, 'errors'> & { errors: ReadonlyArray<ResolversParentTypes['Error']> };
39904005
SupportMessage: SupportMessage;
4006+
TelegramPassportNonce: Scalars['TelegramPassportNonce']['output'];
39914007
Timestamp: Scalars['Timestamp']['output'];
39924008
TotpCode: Scalars['TotpCode']['output'];
39934009
TotpRegistrationId: Scalars['TotpRegistrationId']['output'];
@@ -4009,6 +4025,7 @@ export type ResolversParentTypes = {
40094025
UserEmailRegistrationValidatePayload: Omit<UserEmailRegistrationValidatePayload, 'errors' | 'me'> & { errors: ReadonlyArray<ResolversParentTypes['Error']>, me?: Maybe<ResolversParentTypes['User']> };
40104026
UserLoginInput: UserLoginInput;
40114027
UserLoginUpgradeInput: UserLoginUpgradeInput;
4028+
UserLoginUpgradeTelegramInput: UserLoginUpgradeTelegramInput;
40124029
UserLogoutInput: UserLogoutInput;
40134030
UserPhoneDeletePayload: Omit<UserPhoneDeletePayload, 'errors' | 'me'> & { errors: ReadonlyArray<ResolversParentTypes['Error']>, me?: Maybe<ResolversParentTypes['User']> };
40144031
UserPhoneRegistrationInitiateInput: UserPhoneRegistrationInitiateInput;
@@ -4626,6 +4643,7 @@ export type MutationResolvers<ContextType = any, ParentType extends ResolversPar
46264643
userEmailRegistrationValidate?: Resolver<ResolversTypes['UserEmailRegistrationValidatePayload'], ParentType, ContextType, RequireFields<MutationUserEmailRegistrationValidateArgs, 'input'>>;
46274644
userLogin?: Resolver<ResolversTypes['AuthTokenPayload'], ParentType, ContextType, RequireFields<MutationUserLoginArgs, 'input'>>;
46284645
userLoginUpgrade?: Resolver<ResolversTypes['UpgradePayload'], ParentType, ContextType, RequireFields<MutationUserLoginUpgradeArgs, 'input'>>;
4646+
userLoginUpgradeTelegram?: Resolver<ResolversTypes['UpgradePayload'], ParentType, ContextType, RequireFields<MutationUserLoginUpgradeTelegramArgs, 'input'>>;
46294647
userLogout?: Resolver<ResolversTypes['SuccessPayload'], ParentType, ContextType, Partial<MutationUserLogoutArgs>>;
46304648
userPhoneDelete?: Resolver<ResolversTypes['UserPhoneDeletePayload'], ParentType, ContextType>;
46314649
userPhoneRegistrationInitiate?: Resolver<ResolversTypes['SuccessPayload'], ParentType, ContextType, RequireFields<MutationUserPhoneRegistrationInitiateArgs, 'input'>>;
@@ -4967,6 +4985,10 @@ export type SupportMessageResolvers<ContextType = any, ParentType extends Resolv
49674985
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
49684986
};
49694987

4988+
export interface TelegramPassportNonceScalarConfig extends GraphQLScalarTypeConfig<ResolversTypes['TelegramPassportNonce'], any> {
4989+
name: 'TelegramPassportNonce';
4990+
}
4991+
49704992
export interface TimestampScalarConfig extends GraphQLScalarTypeConfig<ResolversTypes['Timestamp'], any> {
49714993
name: 'Timestamp';
49724994
}
@@ -5304,6 +5326,7 @@ export type Resolvers<ContextType = any> = {
53045326
SuccessPayload?: SuccessPayloadResolvers<ContextType>;
53055327
SupportChatMessageAddPayload?: SupportChatMessageAddPayloadResolvers<ContextType>;
53065328
SupportMessage?: SupportMessageResolvers<ContextType>;
5329+
TelegramPassportNonce?: GraphQLScalarType;
53075330
Timestamp?: GraphQLScalarType;
53085331
TotpCode?: GraphQLScalarType;
53095332
TotpRegistrationId?: GraphQLScalarType;

apps/map/codegen.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@ generates:
6666
ContactHandle: "string"
6767
ContactType: "string"
6868
ContactDisplayName: "string"
69+
TelegramPassportNonce: "string"

apps/map/services/galoy/graphql/generated.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export type Scalars = {
7272
SignedAmount: { input: number; output: number; }
7373
/** A string amount (of a currency) that can be negative (e.g. in a transaction) */
7474
SignedDisplayMajorAmount: { input: string; output: string; }
75+
/** Nonce provided by Telegram Passport to validate the login/upgrade flow */
76+
TelegramPassportNonce: { input: string; output: string; }
7577
/** Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) */
7678
Timestamp: { input: number; output: number; }
7779
/** A time-based one-time password */
@@ -1045,6 +1047,7 @@ export type Mutation = {
10451047
readonly userEmailRegistrationValidate: UserEmailRegistrationValidatePayload;
10461048
readonly userLogin: AuthTokenPayload;
10471049
readonly userLoginUpgrade: UpgradePayload;
1050+
readonly userLoginUpgradeTelegram: UpgradePayload;
10481051
readonly userLogout: SuccessPayload;
10491052
readonly userPhoneDelete: UserPhoneDeletePayload;
10501053
readonly userPhoneRegistrationInitiate: SuccessPayload;
@@ -1283,6 +1286,11 @@ export type MutationUserLoginUpgradeArgs = {
12831286
};
12841287

12851288

1289+
export type MutationUserLoginUpgradeTelegramArgs = {
1290+
input: UserLoginUpgradeTelegramInput;
1291+
};
1292+
1293+
12861294
export type MutationUserLogoutArgs = {
12871295
input?: InputMaybe<UserLogoutInput>;
12881296
};
@@ -2078,6 +2086,11 @@ export type UserLoginUpgradeInput = {
20782086
readonly phone: Scalars['Phone']['input'];
20792087
};
20802088

2089+
export type UserLoginUpgradeTelegramInput = {
2090+
readonly nonce: Scalars['TelegramPassportNonce']['input'];
2091+
readonly phone: Scalars['Phone']['input'];
2092+
};
2093+
20812094
export type UserLogoutInput = {
20822095
readonly deviceToken: Scalars['String']['input'];
20832096
};
@@ -2360,4 +2373,4 @@ export function useBusinessMapMarkersSuspenseQuery(baseOptions?: Apollo.SkipToke
23602373
export type BusinessMapMarkersQueryHookResult = ReturnType<typeof useBusinessMapMarkersQuery>;
23612374
export type BusinessMapMarkersLazyQueryHookResult = ReturnType<typeof useBusinessMapMarkersLazyQuery>;
23622375
export type BusinessMapMarkersSuspenseQueryHookResult = ReturnType<typeof useBusinessMapMarkersSuspenseQuery>;
2363-
export type BusinessMapMarkersQueryResult = Apollo.QueryResult<BusinessMapMarkersQuery, BusinessMapMarkersQueryVariables>;
2376+
export type BusinessMapMarkersQueryResult = Apollo.QueryResult<BusinessMapMarkersQuery, BusinessMapMarkersQueryVariables>;

apps/pay/codegen.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,4 @@ generates:
7474
ContactHandle: "string"
7575
ContactType: "string"
7676
ContactDisplayName: "string"
77+
TelegramPassportNonce: "string"

apps/pay/lib/graphql/generated.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export type Scalars = {
7272
SignedAmount: { input: number; output: number; }
7373
/** A string amount (of a currency) that can be negative (e.g. in a transaction) */
7474
SignedDisplayMajorAmount: { input: string; output: string; }
75+
/** Nonce provided by Telegram Passport to validate the login/upgrade flow */
76+
TelegramPassportNonce: { input: string; output: string; }
7577
/** Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) */
7678
Timestamp: { input: number; output: number; }
7779
/** A time-based one-time password */
@@ -1046,6 +1048,7 @@ export type Mutation = {
10461048
readonly userEmailRegistrationValidate: UserEmailRegistrationValidatePayload;
10471049
readonly userLogin: AuthTokenPayload;
10481050
readonly userLoginUpgrade: UpgradePayload;
1051+
readonly userLoginUpgradeTelegram: UpgradePayload;
10491052
readonly userLogout: SuccessPayload;
10501053
readonly userPhoneDelete: UserPhoneDeletePayload;
10511054
readonly userPhoneRegistrationInitiate: SuccessPayload;
@@ -1284,6 +1287,11 @@ export type MutationUserLoginUpgradeArgs = {
12841287
};
12851288

12861289

1290+
export type MutationUserLoginUpgradeTelegramArgs = {
1291+
input: UserLoginUpgradeTelegramInput;
1292+
};
1293+
1294+
12871295
export type MutationUserLogoutArgs = {
12881296
input?: InputMaybe<UserLogoutInput>;
12891297
};
@@ -2079,6 +2087,11 @@ export type UserLoginUpgradeInput = {
20792087
readonly phone: Scalars['Phone']['input'];
20802088
};
20812089

2090+
export type UserLoginUpgradeTelegramInput = {
2091+
readonly nonce: Scalars['TelegramPassportNonce']['input'];
2092+
readonly phone: Scalars['Phone']['input'];
2093+
};
2094+
20822095
export type UserLogoutInput = {
20832096
readonly deviceToken: Scalars['String']['input'];
20842097
};
@@ -3016,4 +3029,4 @@ export function usePriceSubscription(baseOptions: Apollo.SubscriptionHookOptions
30163029
return Apollo.useSubscription<PriceSubscription, PriceSubscriptionVariables>(PriceDocument, options);
30173030
}
30183031
export type PriceSubscriptionHookResult = ReturnType<typeof usePriceSubscription>;
3019-
export type PriceSubscriptionResult = Apollo.SubscriptionResult<PriceSubscription>;
3032+
export type PriceSubscriptionResult = Apollo.SubscriptionResult<PriceSubscription>;

bats/core/api/auth.bats

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ generateTotpCode() {
153153
curl_request "http://${GALOY_ENDPOINT}/auth/telegram-passport/request-params" "$variables"
154154
nonce=$(curl_output '.nonce')
155155
[ -n "$nonce" ] || exit 1
156+
cache_value "telegram.nonce" "$nonce"
156157

157158
# Step 2: Try to login with the nonce before Telegram Passport webhook is called
158159
variables="{\"nonce\": \"$nonce\", \"phone\": \"$phone\"}"
@@ -186,6 +187,24 @@ generateTotpCode() {
186187
[[ "$error" =~ "Invalid nonce $nonce" ]] || exit 1
187188
}
188189

190+
@test "auth: telegram upgrade fails with used nonce" {
191+
local phone="$(read_value diana.phone)"
192+
local nonce="$(read_value telegram.nonce)"
193+
194+
variables=$(
195+
jq -n \
196+
--arg phone "$phone" \
197+
--arg nonce "$nonce" \
198+
'{input: {phone: $phone, nonce: $nonce}}'
199+
)
200+
201+
exec_graphql 'diana' 'user-login-upgrade-telegram' "$variables"
202+
203+
[[ "$(graphql_output '.data.userLoginUpgradeTelegram.success')" == "false" ]] || exit 1
204+
[[ "$(graphql_output '.data.userLoginUpgradeTelegram.errors[0].code')" == "NOT_FOUND" ]] || exit 1
205+
[[ "$(graphql_output '.data.userLoginUpgradeTelegram.errors[0].message')" == "Invalid nonce ${nonce}" ]] || exit 1
206+
}
207+
189208
@test "auth: remove phone login" {
190209
email=$(read_value 'charlie.email')
191210

bats/core/api/device-account.bats

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
load "../../helpers/_common.bash"
22
load "../../helpers/cli.bash"
33
load "../../helpers/user.bash"
4+
load "../../helpers/telegram.bash"
5+
6+
setup_file() {
7+
clear_cache
8+
}
49

510
DEVICE_NAME="device-user"
611

@@ -46,6 +51,32 @@ jwt="eyJhbGciOiJSUzI1NiIsImtpZCI6IjFiOTdiMjIxLWNhMDgtNGViMi05ZDA5LWE1NzcwZmNjZWI
4651
[[ "$refetched_account_id" == "$account_id" ]] || exit 1
4752
}
4853

54+
@test "device-account: upgrade fails if phone already exists" {
55+
token_name="$DEVICE_NAME"
56+
57+
create_user 'fran'
58+
phone_number="$(read_value fran.phone)"
59+
60+
code="000000"
61+
variables=$(
62+
jq -n \
63+
--arg phone "$phone_number" \
64+
--arg code "$code" \
65+
'{input: {phone: $phone, code: $code}}'
66+
)
67+
exec_graphql "$token_name" 'user-login-upgrade' "$variables"
68+
69+
err_code="$(graphql_output '.data.userLoginUpgrade.errors[0].code')"
70+
if [[ "$err_code" != "PHONE_ALREADY_ATTACHED_ERROR" ]]; then
71+
echo "Unexpected error code: $err_code"
72+
exit 1
73+
fi
74+
75+
exec_graphql "$token_name" 'account-details'
76+
level="$(graphql_output '.data.me.defaultAccount.level')"
77+
[[ "$level" == "ZERO" ]] || exit 1
78+
}
79+
4980
@test "device-account: upgrade" {
5081
token_name="$DEVICE_NAME"
5182
code="000000"
@@ -78,3 +109,50 @@ jwt="eyJhbGciOiJSUzI1NiIsImtpZCI6IjFiOTdiMjIxLWNhMDgtNGViMi05ZDA5LWE1NzcwZmNjZWI
78109
delete_success="$(graphql_output '.data.accountDelete.success')"
79110
[[ "$delete_success" == "true" ]] || exit 1
80111
}
112+
113+
@test "device-account: telegram upgrade success" {
114+
#
115+
# TODO: Remove skip method
116+
#
117+
skip
118+
local token_name="device-user-telegram"
119+
local appcheck_header="Appcheck: $jwt"
120+
121+
local username="$(random_uuid)"
122+
local password="$(random_uuid)"
123+
local basic_token="$(echo -n $username:$password | base64 -w 0)"
124+
local auth_header="Authorization: Basic $basic_token"
125+
126+
curl_request "$url" "" "$auth_header" "$appcheck_header"
127+
local new_token="$(echo $output | jq -r '.result')"
128+
[[ "$new_token" != "null" && -n "$new_token" ]] || exit 1
129+
cache_value "$token_name" "$new_token"
130+
131+
exec_graphql "$token_name" 'account-details'
132+
[[ "$(graphql_output '.data.me.defaultAccount.level')" == "ZERO" ]] || exit 1
133+
134+
# Request nonce
135+
local phone="$(random_phone)"
136+
cache_value "$token_name.phone" "$phone"
137+
curl_request "http://${GALOY_ENDPOINT}/auth/telegram-passport/request-params" "{\"phone\":\"$phone\"}"
138+
local nonce="$(curl_output '.nonce')"
139+
[ -n "$nonce" ] || exit 1
140+
141+
# Pending before webhook
142+
local variables=$(
143+
jq -n \
144+
--arg phone "$phone" \
145+
--arg nonce "$nonce" \
146+
'{input: {phone: $phone, nonce: $nonce}}'
147+
)
148+
exec_graphql "$token_name" 'user-login-upgrade-telegram' "$variables"
149+
[[ "$(graphql_output '.data.userLoginUpgradeTelegram.success')" == "false" ]] || exit 1
150+
151+
simulateTelegramPassportWebhook "$nonce" "${phone//+/}"
152+
153+
exec_graphql "$token_name" 'user-login-upgrade-telegram' "$variables"
154+
[[ "$(graphql_output '.data.userLoginUpgradeTelegram.success')" == "true" ]] || exit 1
155+
156+
exec_graphql "$token_name" 'account-details'
157+
[[ "$(graphql_output '.data.me.defaultAccount.level')" == "ONE" ]] || exit 1
158+
}

0 commit comments

Comments
 (0)