Skip to content

Commit 95b527a

Browse files
committed
android/auth: handle user canceled authentication
1 parent c8f0d15 commit 95b527a

File tree

8 files changed

+61
-5
lines changed

8 files changed

+61
-5
lines changed

backend/backend.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ type authEventType string
117117
const (
118118
authRequired authEventType = "auth-required"
119119
authForced authEventType = "auth-forced"
120+
authCanceled authEventType = "auth-canceled"
120121
authOk authEventType = "auth-ok"
121122
authErr authEventType = "auth-err"
122123
)
@@ -336,6 +337,17 @@ func (backend *Backend) TriggerAuth() {
336337
})
337338
}
338339

340+
// CancelAuth triggers an auth-canceled notification.
341+
func (backend *Backend) CancelAuth() {
342+
backend.Notify(observable.Event{
343+
Subject: "auth",
344+
Action: action.Replace,
345+
Object: authEventObject{
346+
Typ: authCanceled,
347+
},
348+
})
349+
}
350+
339351
// ForceAuth triggers an auth-forced notification
340352
// followed by an auth-required notification.
341353
func (backend *Backend) ForceAuth() {

backend/bridgecommon/bridgecommon.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ func TriggerAuth() {
131131
globalBackend.TriggerAuth()
132132
}
133133

134+
// CancelAuth triggers an authentication canceled notification.
135+
func CancelAuth() {
136+
mu.Lock()
137+
defer mu.Unlock()
138+
if globalBackend == nil {
139+
return
140+
}
141+
globalBackend.CancelAuth()
142+
}
143+
134144
// AuthResult triggers an authentication result notification
135145
// on the base of the input value.
136146
func AuthResult(ok bool) {

frontends/android/BitBoxApp/app/src/main/java/ch/shiftcrypto/bitboxapp/BiometricAuthHelper.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class BiometricAuthHelper {
1616
public interface AuthCallback {
1717
void onSuccess();
1818
void onFailure();
19+
void onCancel();
1920
}
2021

2122
public static void showAuthenticationPrompt(FragmentActivity activity, AuthCallback callback) {
@@ -35,9 +36,14 @@ public void onAuthenticationFailed() {
3536

3637
@Override
3738
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
38-
Util.log("Authentication error: " + errorCode + " - " + errString);
39+
if (errorCode == BiometricPrompt.ERROR_USER_CANCELED) {
40+
Util.log("Authentication error: user canceled");
41+
new Handler(Looper.getMainLooper()).post(callback::onCancel);
42+
} else {
43+
Util.log("Authentication error: " + errorCode + " - " + errString);
44+
new Handler(Looper.getMainLooper()).post(callback::onFailure);
45+
}
3946
super.onAuthenticationError(errorCode, errString);
40-
new Handler(Looper.getMainLooper()).post(callback::onFailure);
4147
}
4248
});
4349

@@ -47,7 +53,6 @@ public void onAuthenticationError(int errorCode, @NonNull CharSequence errString
4753
BiometricManager.Authenticators.BIOMETRIC_WEAK)
4854
.setConfirmationRequired(false)
4955
.build();
50-
5156
biometricPrompt.authenticate(promptInfo);
5257
}
5358
}

frontends/android/BitBoxApp/app/src/main/java/ch/shiftcrypto/bitboxapp/MainActivity.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,20 @@ public void onSuccess() {
375375

376376
@Override
377377
public void onFailure() {
378-
// Failed or cancelled
378+
// Failed
379379
Util.log("Auth failed");
380380
goViewModel.closeAuth();;
381381
Goserver.authResult(false);
382382
}
383+
384+
@Override
385+
public void onCancel() {
386+
// Canceled
387+
Util.log("Auth canceled");
388+
goViewModel.closeAuth();;
389+
Goserver.cancelAuth();
390+
391+
}
383392
});
384393
}
385394
});

frontends/android/goserver/goserver.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ func TriggerAuth() {
217217
bridgecommon.TriggerAuth()
218218
}
219219

220+
// CancelAuth triggers an auth canceled notification towards the frontend.
221+
func CancelAuth() {
222+
bridgecommon.CancelAuth()
223+
}
224+
220225
// AuthResult triggers an auth feeedback notification (auth-ok/auth-err) towards the frontend,
221226
// depending on the input value.
222227
func AuthResult(ok bool) {

frontends/web/src/api/backend.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export const forceAuth = (): Promise<void> => {
117117
};
118118

119119
export type TAuthEventObject = {
120-
typ: 'auth-required' | 'auth-forced' | 'auth-ok' | 'auth-err' ;
120+
typ: 'auth-required' | 'auth-forced' | 'auth-canceled' | 'auth-ok' | 'auth-err' ;
121121
};
122122

123123
export const subscribeAuth = (

frontends/web/src/components/auth/authrequired.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ export const AuthRequired = () => {
4444
case 'auth-err':
4545
authenticate(authForced.current);
4646
break;
47+
case 'auth-canceled':
48+
if (authForced.current) {
49+
// forced auth can be dismissed and won't be repeated, as it is
50+
// tied to a specific UI event (e.g. enabling the auth toggle in
51+
// the advanced settings.
52+
setAuthRequired(false);
53+
authForced.current = false;
54+
} else {
55+
authenticate(authForced.current);
56+
}
57+
break;
4758
case 'auth-ok':
4859
setAuthRequired(false);
4960
authForced.current = false;

frontends/web/src/routes/settings/components/advanced-settings/enable-auth-setting.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ export const EnableAuthSetting = ({ backendConfig, onChangeConfig }: TProps) =>
4040
updateConfig(!e.target.checked);
4141
unsubscribe();
4242
}
43+
if (data.typ === 'auth-canceled') {
44+
// if the user canceled the auth, we leave everything as is.
45+
unsubscribe();
46+
}
4347
});
4448
forceAuth();
4549
};

0 commit comments

Comments
 (0)