1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_U2F_h
8 #define mozilla_dom_U2F_h
10 #include "js/TypeDecls.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/dom/BindingDeclarations.h"
13 #include "mozilla/dom/Nullable.h"
14 #include "mozilla/dom/U2FBinding.h"
15 #include "mozilla/dom/WebAuthnManagerBase.h"
16 #include "mozilla/Maybe.h"
17 #include "mozilla/MozPromise.h"
18 #include "nsProxyRelease.h"
19 #include "nsWrapperCache.h"
20 #include "U2FAuthenticator.h"
22 // XXX(Bug 1674080) Remove this and let Codegen.py generate it in U2FBinding.cpp
24 #include "mozilla/dom/Document.h"
31 class WebAuthnMakeCredentialResult
;
32 class WebAuthnGetAssertionResult
;
34 class U2FRegisterCallback
;
35 class U2FSignCallback
;
37 // Defined in U2FBinding.h by the U2F.webidl; their use requires a JSContext.
38 struct RegisterRequest
;
41 class U2FTransaction
{
42 typedef Variant
<nsMainThreadPtrHandle
<U2FRegisterCallback
>,
43 nsMainThreadPtrHandle
<U2FSignCallback
>>
47 explicit U2FTransaction(const U2FCallback
&& aCallback
)
48 : mCallback(std::move(aCallback
)),
50 mVisibilityChanged(false) {
54 bool HasRegisterCallback() {
55 return mCallback
.is
<nsMainThreadPtrHandle
<U2FRegisterCallback
>>();
58 auto& GetRegisterCallback() {
59 return mCallback
.as
<nsMainThreadPtrHandle
<U2FRegisterCallback
>>();
62 bool HasSignCallback() {
63 return mCallback
.is
<nsMainThreadPtrHandle
<U2FSignCallback
>>();
66 auto& GetSignCallback() {
67 return mCallback
.as
<nsMainThreadPtrHandle
<U2FSignCallback
>>();
70 // The callback passed to the API.
71 U2FCallback mCallback
;
73 // Unique transaction id.
76 // Whether or not visibility has changed for the window during this
78 bool mVisibilityChanged
;
81 // Generates a unique id for new transactions. This doesn't have to be unique
82 // forever, it's sufficient to differentiate between temporally close
83 // transactions, where messages can intersect. Can overflow.
84 static uint64_t NextId() {
85 static uint64_t id
= 0;
90 class U2F final
: public WebAuthnManagerBase
, public nsWrapperCache
{
92 NS_DECL_ISUPPORTS_INHERITED
93 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(U2F
,
96 explicit U2F(nsPIDOMWindowInner
* aParent
) : WebAuthnManagerBase(aParent
) {}
98 nsPIDOMWindowInner
* GetParentObject() const { return mParent
; }
100 void Init(ErrorResult
& aRv
);
102 virtual JSObject
* WrapObject(JSContext
* aCx
,
103 JS::Handle
<JSObject
*> aGivenProto
) override
;
106 void Register(const nsAString
& aAppId
,
107 const Sequence
<RegisterRequest
>& aRegisterRequests
,
108 const Sequence
<RegisteredKey
>& aRegisteredKeys
,
109 U2FRegisterCallback
& aCallback
,
110 const Optional
<Nullable
<int32_t>>& opt_aTimeoutSeconds
,
113 void GetRegister(JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aRegisterFunc
,
117 void Sign(const nsAString
& aAppId
, const nsAString
& aChallenge
,
118 const Sequence
<RegisteredKey
>& aRegisteredKeys
,
119 U2FSignCallback
& aCallback
,
120 const Optional
<Nullable
<int32_t>>& opt_aTimeoutSeconds
,
123 void GetSign(JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aSignFunc
,
126 // WebAuthnManagerBase
129 void FinishMakeCredential(
130 const uint64_t& aTransactionId
,
131 const WebAuthnMakeCredentialResult
& aResult
) override
;
134 void FinishGetAssertion(const uint64_t& aTransactionId
,
135 const WebAuthnGetAssertionResult
& aResult
) override
;
138 void RequestAborted(const uint64_t& aTransactionId
,
139 const nsresult
& aError
) override
;
142 // Cancels the current transaction (by sending a Cancel message to the
143 // parent) and rejects it by calling RejectTransaction().
144 MOZ_CAN_RUN_SCRIPT
void CancelTransaction(const nsresult
& aError
);
145 // Upon a visibility change, makes note of it in the current transaction.
146 MOZ_CAN_RUN_SCRIPT
void HandleVisibilityChange() override
;
149 MOZ_CAN_RUN_SCRIPT
~U2F();
151 template <typename T
, typename C
>
152 MOZ_CAN_RUN_SCRIPT
void ExecuteCallback(T
& aResp
,
153 nsMainThreadPtrHandle
<C
>& aCb
);
155 // Rejects the current transaction and clears it.
156 MOZ_CAN_RUN_SCRIPT
void RejectTransaction(const nsresult
& aError
);
158 // Clears all information we have about the current transaction.
159 void ClearTransaction();
163 // The current transaction, if any.
164 Maybe
<U2FTransaction
> mTransaction
;
167 inline void ImplCycleCollectionTraverse(
168 nsCycleCollectionTraversalCallback
& aCallback
, U2FTransaction
& aTransaction
,
169 const char* aName
, uint32_t aFlags
= 0) {
170 if (aTransaction
.HasRegisterCallback()) {
171 CycleCollectionNoteChild(
172 aCallback
, aTransaction
.GetRegisterCallback().get(), aName
, aFlags
);
174 CycleCollectionNoteChild(aCallback
, aTransaction
.GetSignCallback().get(),
179 inline void ImplCycleCollectionUnlink(U2FTransaction
& aTransaction
) {
180 if (aTransaction
.HasRegisterCallback()) {
181 aTransaction
.GetRegisterCallback() = nullptr;
183 aTransaction
.GetSignCallback() = nullptr;
188 } // namespace mozilla
190 #endif // mozilla_dom_U2F_h