forked from credential-handler/credential-handler-polyfill
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
101 lines (86 loc) · 2.98 KB
/
index.js
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
98
99
100
101
/*!
* Copyright (c) 2017-2022 Digital Bazaar, Inc. All rights reserved.
*/
/* global navigator, window */
import {WebAppContext} from 'web-request-rpc';
import {CredentialHandler} from './CredentialHandler.js';
import {CredentialHandlers} from './CredentialHandlers.js';
import {CredentialManager} from './CredentialManager.js';
import {CredentialsContainer} from './CredentialsContainer.js';
import {PermissionManager} from './PermissionManager.js';
import {WebCredential} from './WebCredential.js';
const DEFAULT_MEDIATOR_ORIGIN = 'https://authn.io';
// export classes for testing/TypeScript
export {
CredentialHandler,
CredentialManager,
WebCredential
};
let loaded;
export async function loadOnce(options) {
if(loaded) {
return loaded;
}
loaded = true;
return load(options);
}
export async function load(options = {
mediatorOrigin: DEFAULT_MEDIATOR_ORIGIN
}) {
_assertSecureContext();
// backwards compatibility (`options` used to be a string for expressing
// the full mediator URL)
let mediatorUrl;
if(typeof options === 'string') {
mediatorUrl = options;
} else if(options && typeof options === 'object' &&
typeof options.mediatorOrigin === 'string') {
mediatorUrl = `${options.mediatorOrigin}/mediator`;
} else {
throw new Error(
'"options.mediatorOrigin" must be a string expressing the ' +
'origin of the mediator.');
}
// temporarily still using this for setting permissions and other
// non-get/store APIs
const appContext = new WebAppContext();
const injector = appContext.createWindow(mediatorUrl, {
className: 'credential-mediator',
// 30 second timeout for loading the mediator
timeout: 30000
});
// ensure backdrop is transparent by default
const style = document.createElement('style');
style.appendChild(document.createTextNode(
`dialog.web-app-window.credential-mediator > .web-app-window-backdrop {
background-color: rgba(0, 0, 0, 0.25);
}`));
document.body.appendChild(style);
const polyfill = {};
// TODO: only expose certain APIs when appropriate
polyfill.permissions = new PermissionManager(injector);
polyfill.CredentialHandlers = new CredentialHandlers(injector);
polyfill.CredentialHandler = CredentialHandler;
polyfill.CredentialManager = CredentialManager;
polyfill.credentials = new CredentialsContainer(injector);
polyfill.WebCredential = WebCredential;
// expose polyfill
navigator.credentialsPolyfill = polyfill;
// polyfill
if('credentials' in navigator) {
navigator.credentials.get = polyfill.credentials.get.bind(
polyfill.credentials);
navigator.credentials.store = polyfill.credentials.store.bind(
polyfill.credentials);
} else {
navigator.credentials = polyfill.credentials;
}
window.CredentialManager = CredentialManager;
window.WebCredential = WebCredential;
return polyfill;
}
function _assertSecureContext() {
if(!window.isSecureContext) {
throw new DOMException('SecurityError', 'The operation is insecure.')
}
}