forked from mirrors/gecko-dev
Bug 1804728, part 1 - Fetch all identity provider manifests before showing the identity provider chooser, r=timhuang,emilio
This is required to make our Identity Provider chooser pretty. This has minimal privacy impact because these requests are not credentialed. I had to re-define the service for prompts to include these manifests and return indexes into argument arrays, rather than elements of those arrays. Also updating sourcedocs to reflect this new order of calls. Differential Revision: https://phabricator.services.mozilla.com/D168813
This commit is contained in:
parent
868ac163b7
commit
fe5352731c
6 changed files with 185 additions and 71 deletions
|
|
@ -22,6 +22,7 @@
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsStringStream.h"
|
#include "nsStringStream.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
#include "nsURLHelper.h"
|
#include "nsURLHelper.h"
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
|
|
@ -153,13 +154,64 @@ IdentityCredential::DiscoverFromExternalSourceInMainProcess(
|
||||||
nsCOMPtr<nsIPrincipal> principal(aPrincipal);
|
nsCOMPtr<nsIPrincipal> principal(aPrincipal);
|
||||||
RefPtr<CanonicalBrowsingContext> browsingContext(aBrowsingContext);
|
RefPtr<CanonicalBrowsingContext> browsingContext(aBrowsingContext);
|
||||||
|
|
||||||
// Have the user choose a provider then create a credential for that provider.
|
// Construct an array of requests to fetch manifests for every provider.
|
||||||
PromptUserToSelectProvider(aBrowsingContext, aOptions.mProviders.Value())
|
// We need this to show their branding information
|
||||||
|
nsTArray<RefPtr<GetManifestPromise>> manifestPromises;
|
||||||
|
for (const IdentityProvider& provider : aOptions.mProviders.Value()) {
|
||||||
|
RefPtr<GetManifestPromise> manifest =
|
||||||
|
IdentityCredential::CheckRootManifest(aPrincipal, provider)
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[provider, principal](bool valid) {
|
||||||
|
if (valid) {
|
||||||
|
return IdentityCredential::FetchInternalManifest(principal,
|
||||||
|
provider);
|
||||||
|
}
|
||||||
|
return IdentityCredential::GetManifestPromise::
|
||||||
|
CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||||
|
},
|
||||||
|
[](nsresult error) {
|
||||||
|
return IdentityCredential::GetManifestPromise::
|
||||||
|
CreateAndReject(error, __func__);
|
||||||
|
});
|
||||||
|
manifestPromises.AppendElement(manifest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use AllSettled here so that failures will be included- we use default
|
||||||
|
// values there.
|
||||||
|
GetManifestPromise::AllSettled(GetCurrentSerialEventTarget(),
|
||||||
|
manifestPromises)
|
||||||
->Then(
|
->Then(
|
||||||
GetCurrentSerialEventTarget(), __func__,
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
[principal, browsingContext](const IdentityProvider& provider) {
|
[browsingContext, aOptions](
|
||||||
|
const GetManifestPromise::AllSettledPromiseType::ResolveValueType&
|
||||||
|
aResults) {
|
||||||
|
// Convert the
|
||||||
|
// GetManifestPromise::AllSettledPromiseType::ResolveValueType to a
|
||||||
|
// Sequence<MozPromise>
|
||||||
|
CopyableTArray<MozPromise<IdentityInternalManifest, nsresult,
|
||||||
|
true>::ResolveOrRejectValue>
|
||||||
|
results = aResults;
|
||||||
|
const Sequence<MozPromise<IdentityInternalManifest, nsresult,
|
||||||
|
true>::ResolveOrRejectValue>
|
||||||
|
resultsSequence(std::move(results));
|
||||||
|
// The user picks from the providers
|
||||||
|
return PromptUserToSelectProvider(
|
||||||
|
browsingContext, aOptions.mProviders.Value(), resultsSequence);
|
||||||
|
},
|
||||||
|
[](bool error) {
|
||||||
|
return IdentityCredential::GetIdentityProviderWithManifestPromise::
|
||||||
|
CreateAndReject(NS_ERROR_FAILURE, __func__);
|
||||||
|
})
|
||||||
|
->Then(
|
||||||
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
|
[principal, browsingContext](
|
||||||
|
const IdentityProviderWithManifest& providerAndManifest) {
|
||||||
|
IdentityInternalManifest manifest;
|
||||||
|
IdentityProvider provider;
|
||||||
|
Tie(provider, manifest) = providerAndManifest;
|
||||||
return IdentityCredential::CreateCredential(
|
return IdentityCredential::CreateCredential(
|
||||||
principal, browsingContext, provider);
|
principal, browsingContext, provider, manifest);
|
||||||
},
|
},
|
||||||
[](nsresult error) {
|
[](nsresult error) {
|
||||||
return IdentityCredential::GetIPCIdentityCredentialPromise::
|
return IdentityCredential::GetIPCIdentityCredentialPromise::
|
||||||
|
|
@ -200,9 +252,10 @@ IdentityCredential::DiscoverFromExternalSourceInMainProcess(
|
||||||
|
|
||||||
// static
|
// static
|
||||||
RefPtr<IdentityCredential::GetIPCIdentityCredentialPromise>
|
RefPtr<IdentityCredential::GetIPCIdentityCredentialPromise>
|
||||||
IdentityCredential::CreateCredential(nsIPrincipal* aPrincipal,
|
IdentityCredential::CreateCredential(
|
||||||
BrowsingContext* aBrowsingContext,
|
nsIPrincipal* aPrincipal, BrowsingContext* aBrowsingContext,
|
||||||
const IdentityProvider& aProvider) {
|
const IdentityProvider& aProvider,
|
||||||
|
const IdentityInternalManifest& aManifest) {
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
MOZ_ASSERT(aPrincipal);
|
MOZ_ASSERT(aPrincipal);
|
||||||
MOZ_ASSERT(aBrowsingContext);
|
MOZ_ASSERT(aBrowsingContext);
|
||||||
|
|
@ -210,32 +263,8 @@ IdentityCredential::CreateCredential(nsIPrincipal* aPrincipal,
|
||||||
nsCOMPtr<nsIPrincipal> argumentPrincipal = aPrincipal;
|
nsCOMPtr<nsIPrincipal> argumentPrincipal = aPrincipal;
|
||||||
RefPtr<BrowsingContext> browsingContext(aBrowsingContext);
|
RefPtr<BrowsingContext> browsingContext(aBrowsingContext);
|
||||||
|
|
||||||
return IdentityCredential::CheckRootManifest(aPrincipal, aProvider)
|
return IdentityCredential::FetchAccountList(argumentPrincipal, aProvider,
|
||||||
->Then(
|
aManifest)
|
||||||
GetCurrentSerialEventTarget(), __func__,
|
|
||||||
[aProvider, argumentPrincipal](bool valid) {
|
|
||||||
if (valid) {
|
|
||||||
return IdentityCredential::FetchInternalManifest(
|
|
||||||
argumentPrincipal, aProvider);
|
|
||||||
}
|
|
||||||
return IdentityCredential::GetManifestPromise::CreateAndReject(
|
|
||||||
NS_ERROR_FAILURE, __func__);
|
|
||||||
},
|
|
||||||
[](nsresult error) {
|
|
||||||
return IdentityCredential::GetManifestPromise::CreateAndReject(
|
|
||||||
error, __func__);
|
|
||||||
})
|
|
||||||
->Then(
|
|
||||||
GetCurrentSerialEventTarget(), __func__,
|
|
||||||
[argumentPrincipal,
|
|
||||||
aProvider](const IdentityInternalManifest& manifest) {
|
|
||||||
return IdentityCredential::FetchAccountList(argumentPrincipal,
|
|
||||||
aProvider, manifest);
|
|
||||||
},
|
|
||||||
[](nsresult error) {
|
|
||||||
return IdentityCredential::GetAccountListPromise::CreateAndReject(
|
|
||||||
error, __func__);
|
|
||||||
})
|
|
||||||
->Then(
|
->Then(
|
||||||
GetCurrentSerialEventTarget(), __func__,
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
[argumentPrincipal, browsingContext, aProvider](
|
[argumentPrincipal, browsingContext, aProvider](
|
||||||
|
|
@ -250,7 +279,7 @@ IdentityCredential::CreateCredential(nsIPrincipal* aPrincipal,
|
||||||
NS_ERROR_FAILURE, __func__);
|
NS_ERROR_FAILURE, __func__);
|
||||||
}
|
}
|
||||||
return PromptUserToSelectAccount(browsingContext, accountList,
|
return PromptUserToSelectAccount(browsingContext, accountList,
|
||||||
currentManifest);
|
aProvider, currentManifest);
|
||||||
},
|
},
|
||||||
[](nsresult error) {
|
[](nsresult error) {
|
||||||
return IdentityCredential::GetAccountPromise::CreateAndReject(
|
return IdentityCredential::GetAccountPromise::CreateAndReject(
|
||||||
|
|
@ -698,14 +727,15 @@ IdentityCredential::FetchMetadata(nsIPrincipal* aPrincipal,
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
RefPtr<IdentityCredential::GetIdentityProviderPromise>
|
RefPtr<IdentityCredential::GetIdentityProviderWithManifestPromise>
|
||||||
IdentityCredential::PromptUserToSelectProvider(
|
IdentityCredential::PromptUserToSelectProvider(
|
||||||
BrowsingContext* aBrowsingContext,
|
BrowsingContext* aBrowsingContext,
|
||||||
const Sequence<IdentityProvider>& aProviders) {
|
const Sequence<IdentityProvider>& aProviders,
|
||||||
|
const Sequence<GetManifestPromise::ResolveOrRejectValue>& aManifests) {
|
||||||
MOZ_ASSERT(aBrowsingContext);
|
MOZ_ASSERT(aBrowsingContext);
|
||||||
RefPtr<IdentityCredential::GetIdentityProviderPromise::Private>
|
RefPtr<IdentityCredential::GetIdentityProviderWithManifestPromise::Private>
|
||||||
resultPromise =
|
resultPromise = new IdentityCredential::
|
||||||
new IdentityCredential::GetIdentityProviderPromise::Private(__func__);
|
GetIdentityProviderWithManifestPromise::Private(__func__);
|
||||||
|
|
||||||
if (NS_WARN_IF(!aBrowsingContext)) {
|
if (NS_WARN_IF(!aBrowsingContext)) {
|
||||||
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
|
@ -734,19 +764,53 @@ IdentityCredential::PromptUserToSelectProvider(
|
||||||
return resultPromise;
|
return resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert each settled MozPromise into a Nullable<ResolveValue>
|
||||||
|
Sequence<Nullable<IdentityInternalManifest>> manifests;
|
||||||
|
for (GetManifestPromise::ResolveOrRejectValue manifest : aManifests) {
|
||||||
|
if (manifest.IsResolve()) {
|
||||||
|
if (NS_WARN_IF(
|
||||||
|
!manifests.AppendElement(manifest.ResolveValue(), fallible))) {
|
||||||
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
return resultPromise;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (NS_WARN_IF(!manifests.AppendElement(
|
||||||
|
Nullable<IdentityInternalManifest>(), fallible))) {
|
||||||
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
return resultPromise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JS::Rooted<JS::Value> manifestsJS(jsapi.cx());
|
||||||
|
success = ToJSValue(jsapi.cx(), manifests, &manifestsJS);
|
||||||
|
if (NS_WARN_IF(!success)) {
|
||||||
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
return resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<Promise> showPromptPromise;
|
RefPtr<Promise> showPromptPromise;
|
||||||
icPromptService->ShowProviderPrompt(aBrowsingContext, providersJS,
|
icPromptService->ShowProviderPrompt(aBrowsingContext, providersJS,
|
||||||
|
manifestsJS,
|
||||||
getter_AddRefs(showPromptPromise));
|
getter_AddRefs(showPromptPromise));
|
||||||
|
|
||||||
RefPtr<DomPromiseListener> listener = new DomPromiseListener(
|
RefPtr<DomPromiseListener> listener = new DomPromiseListener(
|
||||||
[resultPromise](JSContext* aCx, JS::Handle<JS::Value> aValue) {
|
[aProviders, aManifests, resultPromise](JSContext* aCx,
|
||||||
IdentityProvider result;
|
JS::Handle<JS::Value> aValue) {
|
||||||
bool success = result.Init(aCx, aValue);
|
int32_t result = aValue.toInt32();
|
||||||
if (!success) {
|
if (result < 0 || (uint32_t)result > aProviders.Length() ||
|
||||||
|
(uint32_t)result > aManifests.Length()) {
|
||||||
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resultPromise->Resolve(result, __func__);
|
const IdentityProvider& resolvedProvider = aProviders.ElementAt(result);
|
||||||
|
if (!aManifests.ElementAt(result).IsResolve()) {
|
||||||
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const IdentityInternalManifest& resolvedManifest =
|
||||||
|
aManifests.ElementAt(result).ResolveValue();
|
||||||
|
resultPromise->Resolve(MakeTuple(resolvedProvider, resolvedManifest),
|
||||||
|
__func__);
|
||||||
},
|
},
|
||||||
[resultPromise](nsresult aRv) { resultPromise->Reject(aRv, __func__); });
|
[resultPromise](nsresult aRv) { resultPromise->Reject(aRv, __func__); });
|
||||||
showPromptPromise->AppendNativeHandler(listener);
|
showPromptPromise->AppendNativeHandler(listener);
|
||||||
|
|
@ -758,6 +822,7 @@ IdentityCredential::PromptUserToSelectProvider(
|
||||||
RefPtr<IdentityCredential::GetAccountPromise>
|
RefPtr<IdentityCredential::GetAccountPromise>
|
||||||
IdentityCredential::PromptUserToSelectAccount(
|
IdentityCredential::PromptUserToSelectAccount(
|
||||||
BrowsingContext* aBrowsingContext, const IdentityAccountList& aAccounts,
|
BrowsingContext* aBrowsingContext, const IdentityAccountList& aAccounts,
|
||||||
|
const IdentityProvider& aProvider,
|
||||||
const IdentityInternalManifest& aManifest) {
|
const IdentityInternalManifest& aManifest) {
|
||||||
MOZ_ASSERT(aBrowsingContext);
|
MOZ_ASSERT(aBrowsingContext);
|
||||||
RefPtr<IdentityCredential::GetAccountPromise::Private> resultPromise =
|
RefPtr<IdentityCredential::GetAccountPromise::Private> resultPromise =
|
||||||
|
|
@ -790,19 +855,37 @@ IdentityCredential::PromptUserToSelectAccount(
|
||||||
return resultPromise;
|
return resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> providerJS(jsapi.cx());
|
||||||
|
success = ToJSValue(jsapi.cx(), aProvider, &providerJS);
|
||||||
|
if (NS_WARN_IF(!success)) {
|
||||||
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
return resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> manifestJS(jsapi.cx());
|
||||||
|
success = ToJSValue(jsapi.cx(), aManifest, &manifestJS);
|
||||||
|
if (NS_WARN_IF(!success)) {
|
||||||
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
|
return resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<Promise> showPromptPromise;
|
RefPtr<Promise> showPromptPromise;
|
||||||
icPromptService->ShowAccountListPrompt(aBrowsingContext, accountsJS,
|
icPromptService->ShowAccountListPrompt(aBrowsingContext, accountsJS,
|
||||||
|
providerJS, manifestJS,
|
||||||
getter_AddRefs(showPromptPromise));
|
getter_AddRefs(showPromptPromise));
|
||||||
|
|
||||||
RefPtr<DomPromiseListener> listener = new DomPromiseListener(
|
RefPtr<DomPromiseListener> listener = new DomPromiseListener(
|
||||||
[resultPromise, aManifest](JSContext* aCx, JS::Handle<JS::Value> aValue) {
|
[aAccounts, resultPromise, aManifest](JSContext* aCx,
|
||||||
IdentityAccount result;
|
JS::Handle<JS::Value> aValue) {
|
||||||
bool success = result.Init(aCx, aValue);
|
int32_t result = aValue.toInt32();
|
||||||
if (!success) {
|
if (!aAccounts.mAccounts.WasPassed() || result < 0 ||
|
||||||
|
(uint32_t)result > aAccounts.mAccounts.Value().Length()) {
|
||||||
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
resultPromise->Reject(NS_ERROR_FAILURE, __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
resultPromise->Resolve(MakeTuple(aManifest, result), __func__);
|
const IdentityAccount& resolved =
|
||||||
|
aAccounts.mAccounts.Value().ElementAt(result);
|
||||||
|
resultPromise->Resolve(MakeTuple(aManifest, resolved), __func__);
|
||||||
},
|
},
|
||||||
[resultPromise](nsresult aRv) { resultPromise->Reject(aRv, __func__); });
|
[resultPromise](nsresult aRv) { resultPromise->Reject(aRv, __func__); });
|
||||||
showPromptPromise->AppendNativeHandler(listener);
|
showPromptPromise->AppendNativeHandler(listener);
|
||||||
|
|
@ -861,7 +944,7 @@ IdentityCredential::PromptUserWithPolicy(
|
||||||
return FetchMetadata(aPrincipal, aProvider, aManifest)
|
return FetchMetadata(aPrincipal, aProvider, aManifest)
|
||||||
->Then(
|
->Then(
|
||||||
GetCurrentSerialEventTarget(), __func__,
|
GetCurrentSerialEventTarget(), __func__,
|
||||||
[aAccount, aProvider, argumentPrincipal, browsingContext,
|
[aAccount, aManifest, aProvider, argumentPrincipal, browsingContext,
|
||||||
icStorageService,
|
icStorageService,
|
||||||
idpPrincipal](const IdentityClientMetadata& metadata)
|
idpPrincipal](const IdentityClientMetadata& metadata)
|
||||||
-> RefPtr<GenericPromise> {
|
-> RefPtr<GenericPromise> {
|
||||||
|
|
@ -892,10 +975,16 @@ IdentityCredential::PromptUserWithPolicy(
|
||||||
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE,
|
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE,
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
JS::Rooted<JS::Value> manifestJS(jsapi.cx());
|
||||||
|
success = ToJSValue(jsapi.cx(), aManifest, &manifestJS);
|
||||||
|
if (NS_WARN_IF(!success)) {
|
||||||
|
return GenericPromise::CreateAndReject(NS_ERROR_FAILURE,
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<Promise> showPromptPromise;
|
RefPtr<Promise> showPromptPromise;
|
||||||
icPromptService->ShowPolicyPrompt(
|
icPromptService->ShowPolicyPrompt(
|
||||||
browsingContext, providerJS, metadataJS,
|
browsingContext, providerJS, manifestJS, metadataJS,
|
||||||
getter_AddRefs(showPromptPromise));
|
getter_AddRefs(showPromptPromise));
|
||||||
|
|
||||||
RefPtr<GenericPromise::Private> resultPromise =
|
RefPtr<GenericPromise::Private> resultPromise =
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ class IdentityCredential final : public Credential {
|
||||||
typedef MozPromise<bool, nsresult, true> ValidationPromise;
|
typedef MozPromise<bool, nsresult, true> ValidationPromise;
|
||||||
typedef MozPromise<IdentityInternalManifest, nsresult, true>
|
typedef MozPromise<IdentityInternalManifest, nsresult, true>
|
||||||
GetManifestPromise;
|
GetManifestPromise;
|
||||||
|
typedef Tuple<IdentityProvider, IdentityInternalManifest>
|
||||||
|
IdentityProviderWithManifest;
|
||||||
|
typedef MozPromise<IdentityProviderWithManifest, nsresult, true>
|
||||||
|
GetIdentityProviderWithManifestPromise;
|
||||||
typedef MozPromise<Tuple<IdentityInternalManifest, IdentityAccountList>,
|
typedef MozPromise<Tuple<IdentityInternalManifest, IdentityAccountList>,
|
||||||
nsresult, true>
|
nsresult, true>
|
||||||
GetAccountListPromise;
|
GetAccountListPromise;
|
||||||
|
|
@ -124,6 +128,7 @@ class IdentityCredential final : public Credential {
|
||||||
// aPrincipal: the caller of navigator.credentials.get()'s principal
|
// aPrincipal: the caller of navigator.credentials.get()'s principal
|
||||||
// aBrowsingContext: the BC of the caller of navigator.credentials.get()
|
// aBrowsingContext: the BC of the caller of navigator.credentials.get()
|
||||||
// aProvider: the provider to validate the root manifest of
|
// aProvider: the provider to validate the root manifest of
|
||||||
|
// aManifest: the internal manifest of the identity provider
|
||||||
// Return value:
|
// Return value:
|
||||||
// a promise resolving to an IPC credential with type "identity", id
|
// a promise resolving to an IPC credential with type "identity", id
|
||||||
// constructed to identify it, and token corresponding to the token
|
// constructed to identify it, and token corresponding to the token
|
||||||
|
|
@ -133,7 +138,8 @@ class IdentityCredential final : public Credential {
|
||||||
// other static methods here.
|
// other static methods here.
|
||||||
static RefPtr<GetIPCIdentityCredentialPromise> CreateCredential(
|
static RefPtr<GetIPCIdentityCredentialPromise> CreateCredential(
|
||||||
nsIPrincipal* aPrincipal, BrowsingContext* aBrowsingContext,
|
nsIPrincipal* aPrincipal, BrowsingContext* aBrowsingContext,
|
||||||
const IdentityProvider& aProvider);
|
const IdentityProvider& aProvider,
|
||||||
|
const IdentityInternalManifest& aManifest);
|
||||||
|
|
||||||
// Performs a Fetch for the root manifest of the provided identity provider
|
// Performs a Fetch for the root manifest of the provided identity provider
|
||||||
// and validates it as correct. The returned promise resolves with a bool
|
// and validates it as correct. The returned promise resolves with a bool
|
||||||
|
|
@ -235,14 +241,17 @@ class IdentityCredential final : public Credential {
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// aBrowsingContext: the BC of the caller of navigator.credentials.get()
|
// aBrowsingContext: the BC of the caller of navigator.credentials.get()
|
||||||
// aProviders: the providers to let the user select from
|
// aProviders: the providers to let the user select from
|
||||||
|
// aManifests: the manifests
|
||||||
// Return value:
|
// Return value:
|
||||||
// a promise resolving to an identity provider that the user took action
|
// a promise resolving to an identity provider that the user took action
|
||||||
// to select. This promise may reject with nsresult errors.
|
// to select. This promise may reject with nsresult errors.
|
||||||
// Side effects:
|
// Side effects:
|
||||||
// Will show a dialog to the user.
|
// Will show a dialog to the user.
|
||||||
static RefPtr<GetIdentityProviderPromise> PromptUserToSelectProvider(
|
static RefPtr<GetIdentityProviderWithManifestPromise>
|
||||||
|
PromptUserToSelectProvider(
|
||||||
BrowsingContext* aBrowsingContext,
|
BrowsingContext* aBrowsingContext,
|
||||||
const Sequence<IdentityProvider>& aProviders);
|
const Sequence<IdentityProvider>& aProviders,
|
||||||
|
const Sequence<GetManifestPromise::ResolveOrRejectValue>& aManifests);
|
||||||
|
|
||||||
// Show the user a dialog to select what account they would like
|
// Show the user a dialog to select what account they would like
|
||||||
// to try to log in with.
|
// to try to log in with.
|
||||||
|
|
@ -250,6 +259,7 @@ class IdentityCredential final : public Credential {
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// aBrowsingContext: the BC of the caller of navigator.credentials.get()
|
// aBrowsingContext: the BC of the caller of navigator.credentials.get()
|
||||||
// aAccounts: the accounts to let the user select from
|
// aAccounts: the accounts to let the user select from
|
||||||
|
// aProvider: the provider that was chosen
|
||||||
// aManifest: the identity provider that was chosen's manifest
|
// aManifest: the identity provider that was chosen's manifest
|
||||||
// Return value:
|
// Return value:
|
||||||
// a promise resolving to an account that the user took action
|
// a promise resolving to an account that the user took action
|
||||||
|
|
@ -258,6 +268,7 @@ class IdentityCredential final : public Credential {
|
||||||
// Will show a dialog to the user.
|
// Will show a dialog to the user.
|
||||||
static RefPtr<GetAccountPromise> PromptUserToSelectAccount(
|
static RefPtr<GetAccountPromise> PromptUserToSelectAccount(
|
||||||
BrowsingContext* aBrowsingContext, const IdentityAccountList& aAccounts,
|
BrowsingContext* aBrowsingContext, const IdentityAccountList& aAccounts,
|
||||||
|
const IdentityProvider& aProvider,
|
||||||
const IdentityInternalManifest& aManifest);
|
const IdentityInternalManifest& aManifest);
|
||||||
|
|
||||||
// Show the user a dialog to select what account they would like
|
// Show the user a dialog to select what account they would like
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,16 @@ A few notes:
|
||||||
"CredentialsContainer::Get" -> "DiscoverFromExternalSource"
|
"CredentialsContainer::Get" -> "DiscoverFromExternalSource"
|
||||||
"DiscoverFromExternalSource" -> "DiscoverFromExternalSourceInMainProcess" [label="IPC via WindowGlobal's DiscoverIdentityCredentialFromExternalSource"]
|
"DiscoverFromExternalSource" -> "DiscoverFromExternalSourceInMainProcess" [label="IPC via WindowGlobal's DiscoverIdentityCredentialFromExternalSource"]
|
||||||
"DiscoverFromExternalSourceInMainProcess" -> "anonymous timeout callback" -> "CloseUserInterface" -> "IdentityCredentialPromptService::Close"
|
"DiscoverFromExternalSourceInMainProcess" -> "anonymous timeout callback" -> "CloseUserInterface" -> "IdentityCredentialPromptService::Close"
|
||||||
"DiscoverFromExternalSourceInMainProcess" -> "PromptUserToSelectProvider"
|
"DiscoverFromExternalSourceInMainProcess" -> "CheckRootManifest A"
|
||||||
|
"CheckRootManifest A" -> "FetchInternalManifest A" [label="via promise chain in DiscoverFromExternalSourceInMainProcess"]
|
||||||
|
"FetchInternalManifest A" -> "DiscoverFromExternalSourceInMainProcess inline anonymous callback (Promise::All)"
|
||||||
|
"DiscoverFromExternalSourceInMainProcess" -> "CheckRootManifest N"
|
||||||
|
"CheckRootManifest N" -> "FetchInternalManifest N" [label="via promise chain in DiscoverFromExternalSourceInMainProcess"]
|
||||||
|
"FetchInternalManifest N" -> "DiscoverFromExternalSourceInMainProcess inline anonymous callback (Promise::All)"
|
||||||
|
"DiscoverFromExternalSourceInMainProcess inline anonymous callback (Promise::All)" -> "PromptUserToSelectProvider"
|
||||||
"PromptUserToSelectProvider" -> "IdentityCredentialPromptService::ShowProviderPrompt"
|
"PromptUserToSelectProvider" -> "IdentityCredentialPromptService::ShowProviderPrompt"
|
||||||
"IdentityCredentialPromptService::ShowProviderPrompt" -> "CreateCredential" [label="via promise chain in DiscoverFromExternalSourceInMainProcess"]
|
"IdentityCredentialPromptService::ShowProviderPrompt" -> "CreateCredential" [label="via promise chain in DiscoverFromExternalSourceInMainProcess"]
|
||||||
"CreateCredential" -> "CheckRootManifest"
|
"CreateCredential" -> "FetchAccountList" [label="via promise chain in CreateCredential"]
|
||||||
"CheckRootManifest" -> "FetchInternalManifest" [label="via promise chain in CreateCredential"]
|
|
||||||
"FetchInternalManifest" -> "FetchAccountList" [label="via promise chain in CreateCredential"]
|
|
||||||
"FetchAccountList" -> "PromptUserToSelectAccount" [label="via promise chain in CreateCredential"]
|
"FetchAccountList" -> "PromptUserToSelectAccount" [label="via promise chain in CreateCredential"]
|
||||||
"PromptUserToSelectAccount" -> "IdentityCredentialPromptService::ShowAccountListPrompt"
|
"PromptUserToSelectAccount" -> "IdentityCredentialPromptService::ShowAccountListPrompt"
|
||||||
"IdentityCredentialPromptService::ShowAccountListPrompt" -> "PromptUserWithPolicy" [label="via promise chain in CreateCredential"]
|
"IdentityCredentialPromptService::ShowAccountListPrompt" -> "PromptUserWithPolicy" [label="via promise chain in CreateCredential"]
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ dictionary IdentityBranding {
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://fedidcg.github.io/FedCM/#manifest
|
// https://fedidcg.github.io/FedCM/#manifest
|
||||||
[GenerateInit]
|
[GenerateInit, GenerateConversionToJS]
|
||||||
dictionary IdentityInternalManifest {
|
dictionary IdentityInternalManifest {
|
||||||
required USVString accounts_endpoint;
|
required USVString accounts_endpoint;
|
||||||
required USVString client_metadata_endpoint;
|
required USVString client_metadata_endpoint;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
|
|
||||||
function fulfilledPromiseFromFirstListElement(list) {
|
function fulfilledPromiseFromFirstListElement(list) {
|
||||||
if (list.length) {
|
if (list.length) {
|
||||||
return Promise.resolve(list[0]);
|
return Promise.resolve(0);
|
||||||
}
|
}
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
|
|
@ -42,9 +42,10 @@ export class IdentityCredentialPromptService {
|
||||||
* Ask the user, using a PopupNotification, to select an Identity Provider from a provided list.
|
* Ask the user, using a PopupNotification, to select an Identity Provider from a provided list.
|
||||||
* @param {BrowsingContext} browsingContext - The BrowsingContext of the document requesting an identity credential via navigator.credentials.get()
|
* @param {BrowsingContext} browsingContext - The BrowsingContext of the document requesting an identity credential via navigator.credentials.get()
|
||||||
* @param {IdentityProvider[]} identityProviders - The list of identity providers the user selects from
|
* @param {IdentityProvider[]} identityProviders - The list of identity providers the user selects from
|
||||||
* @returns {Promise<IdentityProvider>} The user-selected identity provider
|
* @param {IdentityInternalManifest[]} identityManifests - The manifests corresponding 1-to-1 with identityProviders
|
||||||
|
* @returns {Promise<number>} The user-selected identity provider
|
||||||
*/
|
*/
|
||||||
showProviderPrompt(browsingContext, identityProviders) {
|
showProviderPrompt(browsingContext, identityProviders, identityManifests) {
|
||||||
// For testing only.
|
// For testing only.
|
||||||
if (lazy.SELECT_FIRST_IN_UI_LISTS) {
|
if (lazy.SELECT_FIRST_IN_UI_LISTS) {
|
||||||
return fulfilledPromiseFromFirstListElement(identityProviders);
|
return fulfilledPromiseFromFirstListElement(identityProviders);
|
||||||
|
|
@ -101,7 +102,7 @@ export class IdentityCredentialPromptService {
|
||||||
browser
|
browser
|
||||||
);
|
);
|
||||||
browser.ownerGlobal.PopupNotifications.remove(notification);
|
browser.ownerGlobal.PopupNotifications.remove(notification);
|
||||||
resolve(provider);
|
resolve(providerIndex);
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
};
|
};
|
||||||
listBox.append(newItem);
|
listBox.append(newItem);
|
||||||
|
|
@ -152,12 +153,14 @@ export class IdentityCredentialPromptService {
|
||||||
* Ask the user, using a PopupNotification, to approve or disapprove of the policies of the Identity Provider.
|
* Ask the user, using a PopupNotification, to approve or disapprove of the policies of the Identity Provider.
|
||||||
* @param {BrowsingContext} browsingContext - The BrowsingContext of the document requesting an identity credential via navigator.credentials.get()
|
* @param {BrowsingContext} browsingContext - The BrowsingContext of the document requesting an identity credential via navigator.credentials.get()
|
||||||
* @param {IdentityProvider} identityProvider - The Identity Provider that the user has selected to use
|
* @param {IdentityProvider} identityProvider - The Identity Provider that the user has selected to use
|
||||||
|
* @param {IdentityInternalManifest} identityManifest - The Identity Provider that the user has selected to use's manifest
|
||||||
* @param {IdentityCredentialMetadata} identityCredentialMetadata - The metadata displayed to the user
|
* @param {IdentityCredentialMetadata} identityCredentialMetadata - The metadata displayed to the user
|
||||||
* @returns {Promise<bool>} A boolean representing the user's acceptance of the metadata.
|
* @returns {Promise<bool>} A boolean representing the user's acceptance of the metadata.
|
||||||
*/
|
*/
|
||||||
showPolicyPrompt(
|
showPolicyPrompt(
|
||||||
browsingContext,
|
browsingContext,
|
||||||
identityProvider,
|
identityProvider,
|
||||||
|
identityManifest,
|
||||||
identityCredentialMetadata
|
identityCredentialMetadata
|
||||||
) {
|
) {
|
||||||
// For testing only.
|
// For testing only.
|
||||||
|
|
@ -283,9 +286,16 @@ export class IdentityCredentialPromptService {
|
||||||
* Ask the user, using a PopupNotification, to select an account from a provided list.
|
* Ask the user, using a PopupNotification, to select an account from a provided list.
|
||||||
* @param {BrowsingContext} browsingContext - The BrowsingContext of the document requesting an identity credential via navigator.credentials.get()
|
* @param {BrowsingContext} browsingContext - The BrowsingContext of the document requesting an identity credential via navigator.credentials.get()
|
||||||
* @param {IdentityAccountList} accountList - The list of accounts the user selects from
|
* @param {IdentityAccountList} accountList - The list of accounts the user selects from
|
||||||
|
* @param {IdentityProvider} provider - The selected identity provider
|
||||||
|
* @param {IdentityInternalManifest} providerManifest - The manifest of the selected identity provider
|
||||||
* @returns {Promise<IdentityAccount>} The user-selected account
|
* @returns {Promise<IdentityAccount>} The user-selected account
|
||||||
*/
|
*/
|
||||||
showAccountListPrompt(browsingContext, accountList) {
|
showAccountListPrompt(
|
||||||
|
browsingContext,
|
||||||
|
accountList,
|
||||||
|
provider,
|
||||||
|
providerManifest
|
||||||
|
) {
|
||||||
// For testing only.
|
// For testing only.
|
||||||
if (lazy.SELECT_FIRST_IN_UI_LISTS) {
|
if (lazy.SELECT_FIRST_IN_UI_LISTS) {
|
||||||
return fulfilledPromiseFromFirstListElement(accountList.accounts);
|
return fulfilledPromiseFromFirstListElement(accountList.accounts);
|
||||||
|
|
@ -350,7 +360,7 @@ export class IdentityCredentialPromptService {
|
||||||
browser
|
browser
|
||||||
);
|
);
|
||||||
browser.ownerGlobal.PopupNotifications.remove(notification);
|
browser.ownerGlobal.PopupNotifications.remove(notification);
|
||||||
resolve(account);
|
resolve(accountIndex);
|
||||||
};
|
};
|
||||||
listBox.append(newItem);
|
listBox.append(newItem);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,14 @@ webidl BrowsingContext;
|
||||||
[scriptable, uuid(936007db-a957-4f1d-a23d-f7d9403223e6)]
|
[scriptable, uuid(936007db-a957-4f1d-a23d-f7d9403223e6)]
|
||||||
interface nsIIdentityCredentialPromptService : nsISupports {
|
interface nsIIdentityCredentialPromptService : nsISupports {
|
||||||
// Display to the user an interface to choose from among the identity providers listed
|
// Display to the user an interface to choose from among the identity providers listed
|
||||||
// Resolves with one of the elements of the list.
|
// Resolves with an index referring to one pair of the elements of the lists.
|
||||||
Promise showProviderPrompt(in BrowsingContext browsingContext, in jsval identityProviders);
|
Promise showProviderPrompt(in BrowsingContext browsingContext, in jsval identityProviders, in jsval identityManifests);
|
||||||
// Display to the user an interface to approve (or disapprove) of the terms of service for
|
// Display to the user an interface to approve (or disapprove) of the terms of service for
|
||||||
// the identity provider when used on the current site.
|
// the identity provider when used on the current site.
|
||||||
Promise showPolicyPrompt(in BrowsingContext browsingContext, in jsval identityProvider, in jsval identityClientMetadata);
|
Promise showPolicyPrompt(in BrowsingContext browsingContext, in jsval identityProvider, in jsval identityManifest, in jsval identityClientMetadata);
|
||||||
// Display to the user an interface to choose from among the accounts listed.
|
// Display to the user an interface to choose from among the accounts listed with the information of the provider.
|
||||||
// Resolves with one of the elements of the list.
|
// Resolves with an index referring to one of the elements of the list.
|
||||||
Promise showAccountListPrompt(in BrowsingContext browsingContext, in jsval accountList);
|
Promise showAccountListPrompt(in BrowsingContext browsingContext, in jsval accountList, in jsval identityProvider, in jsval identityManifest);
|
||||||
// Close all UI from the other methods of this module
|
// Close all UI from the other methods of this module
|
||||||
void close(in BrowsingContext browsingContext);
|
void close(in BrowsingContext browsingContext);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue