summaryrefslogtreecommitdiffstats
path: root/dom/webauthn/WebAuthnService.h
blob: a3f4dab797186526c24bd21d3d60c0059a53c7da (plain)
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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_WebAuthnService_h_
#define mozilla_dom_WebAuthnService_h_

#include "nsIWebAuthnService.h"
#include "AuthrsBridge_ffi.h"
#include "mozilla/dom/WebAuthnPromiseHolder.h"

#ifdef MOZ_WIDGET_ANDROID
#  include "AndroidWebAuthnService.h"
#endif

#ifdef XP_MACOSX
#  include "MacOSWebAuthnService.h"
#endif

#ifdef XP_WIN
#  include "WinWebAuthnService.h"
#endif

namespace mozilla::dom {

already_AddRefed<nsIWebAuthnService> NewWebAuthnService();

class WebAuthnService final : public nsIWebAuthnService {
 public:
  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECL_NSIWEBAUTHNSERVICE

  WebAuthnService()
      : mTransactionState(Nothing(), "WebAuthnService::mTransactionState") {
    Unused << authrs_service_constructor(getter_AddRefs(mAuthrsService));
#if defined(XP_WIN)
    if (WinWebAuthnService::AreWebAuthNApisAvailable()) {
      mPlatformService = new WinWebAuthnService();
    } else {
      mPlatformService = mAuthrsService;
    }
#elif defined(MOZ_WIDGET_ANDROID)
    mPlatformService = new AndroidWebAuthnService();
#elif defined(XP_MACOSX)
    if (__builtin_available(macos 13.3, *)) {
      mPlatformService = NewMacOSWebAuthnServiceIfAvailable();
    }
    if (!mPlatformService) {
      mPlatformService = mAuthrsService;
    }
#else
    mPlatformService = mAuthrsService;
#endif
  }

 private:
  ~WebAuthnService() = default;

  struct TransactionState {
    nsCOMPtr<nsIWebAuthnService> service;
    uint64_t transactionId;
    Maybe<nsCOMPtr<nsIWebAuthnRegisterPromise>> parentRegisterPromise;
    Maybe<nsCOMPtr<nsIWebAuthnRegisterResult>> registerResult;
    MozPromiseRequestHolder<WebAuthnRegisterPromise> childRegisterRequest;
  };
  using TransactionStateMutex = DataMutex<Maybe<TransactionState>>;
  TransactionStateMutex mTransactionState;

  void ShowAttestationConsentPrompt(const nsString& aOrigin,
                                    uint64_t aTransactionId,
                                    uint64_t aBrowsingContextId);
  void ResetLocked(const TransactionStateMutex::AutoLock& aGuard);

  nsIWebAuthnService* DefaultService() {
    if (StaticPrefs::security_webauth_webauthn_enable_softtoken()) {
      return mAuthrsService;
    }
    return mPlatformService;
  }

  nsIWebAuthnService* AuthrsService() { return mAuthrsService; }

  nsIWebAuthnService* SelectedService() {
    auto guard = mTransactionState.Lock();
    if (guard->isSome()) {
      return guard->ref().service;
    }
    return DefaultService();
  }

  nsCOMPtr<nsIWebAuthnService> mAuthrsService;
  nsCOMPtr<nsIWebAuthnService> mPlatformService;
};

}  // namespace mozilla::dom

#endif  // mozilla_dom_WebAuthnService_h_