@astrox/auth-client 0.0.24 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ import { Identity, SignIdentity } from '@astrox/agent';
2
+ import { DelegationChain } from '@astrox/identity';
3
+ /**
4
+ * List of options for creating an {@link AuthClient}.
5
+ */
6
+ export interface AuthClientCreateOptions {
7
+ /**
8
+ * An identity to use as the base
9
+ */
10
+ identity?: SignIdentity;
11
+ /**
12
+ * Optional storage with get, set, and remove. Uses LocalStorage by default
13
+ */
14
+ storage?: AuthClientStorage;
15
+ }
16
+ export interface AuthClientLoginOptions {
17
+ /**
18
+ * Identity provider. By default, use the identity service.
19
+ */
20
+ identityProvider?: string | URL;
21
+ /**
22
+ * Experiation of the authentication
23
+ */
24
+ maxTimeToLive?: bigint;
25
+ /**
26
+ * Callback once login has completed
27
+ */
28
+ onSuccess?: () => void;
29
+ /**
30
+ * Callback in case authentication fails
31
+ */
32
+ onError?: (error?: string) => void;
33
+ }
34
+ /**
35
+ * Interface for persisting user authentication data
36
+ */
37
+ export interface AuthClientStorage {
38
+ get(key: string): Promise<string | null>;
39
+ set(key: string, value: string): Promise<void>;
40
+ remove(key: string): Promise<void>;
41
+ }
42
+ export declare class LocalStorage implements AuthClientStorage {
43
+ readonly prefix: string;
44
+ private readonly _localStorage?;
45
+ constructor(prefix?: string, _localStorage?: Storage | undefined);
46
+ get(key: string): Promise<string | null>;
47
+ set(key: string, value: string): Promise<void>;
48
+ remove(key: string): Promise<void>;
49
+ private _getLocalStorage;
50
+ }
51
+ export declare class AuthClient {
52
+ private _identity;
53
+ private _key;
54
+ private _chain;
55
+ private _storage;
56
+ private _idpWindow?;
57
+ private _eventHandler?;
58
+ static create(options?: AuthClientCreateOptions): Promise<AuthClient>;
59
+ protected constructor(_identity: Identity, _key: SignIdentity | null, _chain: DelegationChain | null, _storage: AuthClientStorage, _idpWindow?: Window | undefined, _eventHandler?: ((event: MessageEvent) => void) | undefined);
60
+ private _handleSuccess;
61
+ getIdentity(): Identity;
62
+ isAuthenticated(): Promise<boolean>;
63
+ login(options?: AuthClientLoginOptions): Promise<void>;
64
+ private _getEventHandler;
65
+ private _handleFailure;
66
+ private _removeEventListener;
67
+ logout(options?: {
68
+ returnTo?: string;
69
+ }): Promise<void>;
70
+ }
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthClient = exports.LocalStorage = void 0;
4
+ const agent_1 = require("@astrox/agent");
5
+ const authentication_1 = require("@astrox/authentication");
6
+ const identity_1 = require("@astrox/identity");
7
+ const KEY_LOCALSTORAGE_KEY = 'identity';
8
+ const KEY_LOCALSTORAGE_DELEGATION = 'delegation';
9
+ const IDENTITY_PROVIDER_DEFAULT = 'https://identity.ic0.app';
10
+ const IDENTITY_PROVIDER_ENDPOINT = '#authorize';
11
+ async function _deleteStorage(storage) {
12
+ await storage.remove(KEY_LOCALSTORAGE_KEY);
13
+ await storage.remove(KEY_LOCALSTORAGE_DELEGATION);
14
+ }
15
+ class LocalStorage {
16
+ constructor(prefix = 'ic-', _localStorage) {
17
+ this.prefix = prefix;
18
+ this._localStorage = _localStorage;
19
+ }
20
+ get(key) {
21
+ return Promise.resolve(this._getLocalStorage().getItem(this.prefix + key));
22
+ }
23
+ set(key, value) {
24
+ this._getLocalStorage().setItem(this.prefix + key, value);
25
+ return Promise.resolve();
26
+ }
27
+ remove(key) {
28
+ this._getLocalStorage().removeItem(this.prefix + key);
29
+ return Promise.resolve();
30
+ }
31
+ _getLocalStorage() {
32
+ if (this._localStorage) {
33
+ return this._localStorage;
34
+ }
35
+ const ls = typeof window === 'undefined'
36
+ ? typeof global === 'undefined'
37
+ ? typeof self === 'undefined'
38
+ ? undefined
39
+ : self.localStorage
40
+ : global.localStorage
41
+ : window.localStorage;
42
+ if (!ls) {
43
+ throw new Error('Could not find local storage.');
44
+ }
45
+ return ls;
46
+ }
47
+ }
48
+ exports.LocalStorage = LocalStorage;
49
+ class AuthClient {
50
+ constructor(_identity, _key, _chain, _storage,
51
+ // A handle on the IdP window.
52
+ _idpWindow,
53
+ // The event handler for processing events from the IdP.
54
+ _eventHandler) {
55
+ this._identity = _identity;
56
+ this._key = _key;
57
+ this._chain = _chain;
58
+ this._storage = _storage;
59
+ this._idpWindow = _idpWindow;
60
+ this._eventHandler = _eventHandler;
61
+ }
62
+ static async create(options = {}) {
63
+ var _a;
64
+ const storage = (_a = options.storage) !== null && _a !== void 0 ? _a : new LocalStorage('ic-');
65
+ let key = null;
66
+ if (options.identity) {
67
+ key = options.identity;
68
+ }
69
+ else {
70
+ const maybeIdentityStorage = await storage.get(KEY_LOCALSTORAGE_KEY);
71
+ if (maybeIdentityStorage) {
72
+ try {
73
+ key = identity_1.Ed25519KeyIdentity.fromJSON(maybeIdentityStorage);
74
+ }
75
+ catch (e) {
76
+ // Ignore this, this means that the localStorage value isn't a valid Ed25519KeyIdentity
77
+ // serialization.
78
+ }
79
+ }
80
+ }
81
+ let identity = new agent_1.AnonymousIdentity();
82
+ let chain = null;
83
+ if (key) {
84
+ try {
85
+ const chainStorage = await storage.get(KEY_LOCALSTORAGE_DELEGATION);
86
+ if (chainStorage) {
87
+ chain = identity_1.DelegationChain.fromJSON(chainStorage);
88
+ // Verify that the delegation isn't expired.
89
+ if (!authentication_1.isDelegationValid(chain)) {
90
+ await _deleteStorage(storage);
91
+ key = null;
92
+ }
93
+ else {
94
+ identity = identity_1.DelegationIdentity.fromDelegation(key, chain);
95
+ }
96
+ }
97
+ }
98
+ catch (e) {
99
+ console.error(e);
100
+ // If there was a problem loading the chain, delete the key.
101
+ await _deleteStorage(storage);
102
+ key = null;
103
+ }
104
+ }
105
+ return new this(identity, key, chain, storage);
106
+ }
107
+ _handleSuccess(message, onSuccess) {
108
+ var _a;
109
+ const delegations = message.delegations.map(signedDelegation => {
110
+ return {
111
+ delegation: new identity_1.Delegation(signedDelegation.delegation.pubkey, signedDelegation.delegation.expiration, signedDelegation.delegation.targets),
112
+ signature: signedDelegation.signature.buffer,
113
+ };
114
+ });
115
+ const delegationChain = identity_1.DelegationChain.fromDelegations(delegations, message.userPublicKey.buffer);
116
+ const key = this._key;
117
+ if (!key) {
118
+ return;
119
+ }
120
+ this._chain = delegationChain;
121
+ this._identity = identity_1.DelegationIdentity.fromDelegation(key, this._chain);
122
+ (_a = this._idpWindow) === null || _a === void 0 ? void 0 : _a.close();
123
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
124
+ this._removeEventListener();
125
+ }
126
+ getIdentity() {
127
+ return this._identity;
128
+ }
129
+ async isAuthenticated() {
130
+ return !this.getIdentity().getPrincipal().isAnonymous() && this._chain !== null;
131
+ }
132
+ async login(options) {
133
+ var _a, _b, _c;
134
+ let key = this._key;
135
+ if (!key) {
136
+ // Create a new key (whether or not one was in storage).
137
+ key = identity_1.Ed25519KeyIdentity.generate();
138
+ this._key = key;
139
+ await this._storage.set(KEY_LOCALSTORAGE_KEY, JSON.stringify(key));
140
+ }
141
+ // Create the URL of the IDP. (e.g. https://XXXX/#authorize)
142
+ const identityProviderUrl = new URL(((_a = options === null || options === void 0 ? void 0 : options.identityProvider) === null || _a === void 0 ? void 0 : _a.toString()) || IDENTITY_PROVIDER_DEFAULT);
143
+ // Set the correct hash if it isn't already set.
144
+ identityProviderUrl.hash = IDENTITY_PROVIDER_ENDPOINT;
145
+ // If `login` has been called previously, then close/remove any previous windows
146
+ // and event listeners.
147
+ (_b = this._idpWindow) === null || _b === void 0 ? void 0 : _b.close();
148
+ this._removeEventListener();
149
+ // Add an event listener to handle responses.
150
+ this._eventHandler = this._getEventHandler(identityProviderUrl, options);
151
+ window.addEventListener('message', this._eventHandler);
152
+ // Open a new window with the IDP provider.
153
+ this._idpWindow = (_c = window.open(identityProviderUrl.toString(), 'idpWindow')) !== null && _c !== void 0 ? _c : undefined;
154
+ }
155
+ _getEventHandler(identityProviderUrl, options) {
156
+ return async (event) => {
157
+ var _a, _b;
158
+ if (event.origin !== identityProviderUrl.origin) {
159
+ return;
160
+ }
161
+ const message = event.data;
162
+ switch (message.kind) {
163
+ case 'authorize-ready': {
164
+ // IDP is ready. Send a message to request authorization.
165
+ const request = {
166
+ kind: 'authorize-client',
167
+ sessionPublicKey: new Uint8Array((_a = this._key) === null || _a === void 0 ? void 0 : _a.getPublicKey().toDer()),
168
+ maxTimeToLive: options === null || options === void 0 ? void 0 : options.maxTimeToLive,
169
+ };
170
+ (_b = this._idpWindow) === null || _b === void 0 ? void 0 : _b.postMessage(request, identityProviderUrl.origin);
171
+ break;
172
+ }
173
+ case 'authorize-client-success':
174
+ // Create the delegation chain and store it.
175
+ try {
176
+ this._handleSuccess(message, options === null || options === void 0 ? void 0 : options.onSuccess);
177
+ // Setting the storage is moved out of _handleSuccess to make
178
+ // it a sync function. Having _handleSuccess as an async function
179
+ // messes up the jest tests for some reason.
180
+ if (this._chain) {
181
+ await this._storage.set(KEY_LOCALSTORAGE_DELEGATION, JSON.stringify(this._chain.toJSON()));
182
+ }
183
+ }
184
+ catch (err) {
185
+ this._handleFailure(err.message, options === null || options === void 0 ? void 0 : options.onError);
186
+ }
187
+ break;
188
+ case 'authorize-client-failure':
189
+ this._handleFailure(message.text, options === null || options === void 0 ? void 0 : options.onError);
190
+ break;
191
+ default:
192
+ break;
193
+ }
194
+ };
195
+ }
196
+ _handleFailure(errorMessage, onError) {
197
+ var _a;
198
+ (_a = this._idpWindow) === null || _a === void 0 ? void 0 : _a.close();
199
+ onError === null || onError === void 0 ? void 0 : onError(errorMessage);
200
+ this._removeEventListener();
201
+ }
202
+ _removeEventListener() {
203
+ if (this._eventHandler) {
204
+ window.removeEventListener('message', this._eventHandler);
205
+ }
206
+ this._eventHandler = undefined;
207
+ }
208
+ async logout(options = {}) {
209
+ _deleteStorage(this._storage);
210
+ // Reset this auth client to a non-authenticated state.
211
+ this._identity = new agent_1.AnonymousIdentity();
212
+ this._key = null;
213
+ this._chain = null;
214
+ if (options.returnTo) {
215
+ try {
216
+ window.history.pushState({}, '', options.returnTo);
217
+ }
218
+ catch (e) {
219
+ window.location.href = options.returnTo;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ exports.AuthClient = AuthClient;
225
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { Identity, SignIdentity } from '@astrox/agent';
2
+ import { DelegationChain } from '@astrox/identity';
3
+ /**
4
+ * List of options for creating an {@link AuthClient}.
5
+ */
6
+ export interface AuthClientCreateOptions {
7
+ /**
8
+ * An identity to use as the base
9
+ */
10
+ identity?: SignIdentity;
11
+ /**
12
+ * Optional storage with get, set, and remove. Uses LocalStorage by default
13
+ */
14
+ storage?: AuthClientStorage;
15
+ }
16
+ export interface AuthClientLoginOptions {
17
+ /**
18
+ * Identity provider. By default, use the identity service.
19
+ */
20
+ identityProvider?: string | URL;
21
+ /**
22
+ * Experiation of the authentication
23
+ */
24
+ maxTimeToLive?: bigint;
25
+ /**
26
+ * Callback once login has completed
27
+ */
28
+ onSuccess?: () => void;
29
+ /**
30
+ * Callback in case authentication fails
31
+ */
32
+ onError?: (error?: string) => void;
33
+ }
34
+ /**
35
+ * Interface for persisting user authentication data
36
+ */
37
+ export interface AuthClientStorage {
38
+ get(key: string): Promise<string | null>;
39
+ set(key: string, value: string): Promise<void>;
40
+ remove(key: string): Promise<void>;
41
+ }
42
+ export declare class LocalStorage implements AuthClientStorage {
43
+ readonly prefix: string;
44
+ private readonly _localStorage?;
45
+ constructor(prefix?: string, _localStorage?: Storage | undefined);
46
+ get(key: string): Promise<string | null>;
47
+ set(key: string, value: string): Promise<void>;
48
+ remove(key: string): Promise<void>;
49
+ private _getLocalStorage;
50
+ }
51
+ export declare class AuthClient {
52
+ private _identity;
53
+ private _key;
54
+ private _chain;
55
+ private _storage;
56
+ private _idpWindow?;
57
+ private _eventHandler?;
58
+ static create(options?: AuthClientCreateOptions): Promise<AuthClient>;
59
+ protected constructor(_identity: Identity, _key: SignIdentity | null, _chain: DelegationChain | null, _storage: AuthClientStorage, _idpWindow?: Window | undefined, _eventHandler?: ((event: MessageEvent) => void) | undefined);
60
+ private _handleSuccess;
61
+ getIdentity(): Identity;
62
+ isAuthenticated(): Promise<boolean>;
63
+ login(options?: AuthClientLoginOptions): Promise<void>;
64
+ private _getEventHandler;
65
+ private _handleFailure;
66
+ private _removeEventListener;
67
+ logout(options?: {
68
+ returnTo?: string;
69
+ }): Promise<void>;
70
+ }
@@ -0,0 +1,220 @@
1
+ import { AnonymousIdentity, } from '@astrox/agent';
2
+ import { isDelegationValid } from '@astrox/authentication';
3
+ import { Delegation, DelegationChain, DelegationIdentity, Ed25519KeyIdentity, } from '@astrox/identity';
4
+ const KEY_LOCALSTORAGE_KEY = 'identity';
5
+ const KEY_LOCALSTORAGE_DELEGATION = 'delegation';
6
+ const IDENTITY_PROVIDER_DEFAULT = 'https://identity.ic0.app';
7
+ const IDENTITY_PROVIDER_ENDPOINT = '#authorize';
8
+ async function _deleteStorage(storage) {
9
+ await storage.remove(KEY_LOCALSTORAGE_KEY);
10
+ await storage.remove(KEY_LOCALSTORAGE_DELEGATION);
11
+ }
12
+ export class LocalStorage {
13
+ constructor(prefix = 'ic-', _localStorage) {
14
+ this.prefix = prefix;
15
+ this._localStorage = _localStorage;
16
+ }
17
+ get(key) {
18
+ return Promise.resolve(this._getLocalStorage().getItem(this.prefix + key));
19
+ }
20
+ set(key, value) {
21
+ this._getLocalStorage().setItem(this.prefix + key, value);
22
+ return Promise.resolve();
23
+ }
24
+ remove(key) {
25
+ this._getLocalStorage().removeItem(this.prefix + key);
26
+ return Promise.resolve();
27
+ }
28
+ _getLocalStorage() {
29
+ if (this._localStorage) {
30
+ return this._localStorage;
31
+ }
32
+ const ls = typeof window === 'undefined'
33
+ ? typeof global === 'undefined'
34
+ ? typeof self === 'undefined'
35
+ ? undefined
36
+ : self.localStorage
37
+ : global.localStorage
38
+ : window.localStorage;
39
+ if (!ls) {
40
+ throw new Error('Could not find local storage.');
41
+ }
42
+ return ls;
43
+ }
44
+ }
45
+ export class AuthClient {
46
+ constructor(_identity, _key, _chain, _storage,
47
+ // A handle on the IdP window.
48
+ _idpWindow,
49
+ // The event handler for processing events from the IdP.
50
+ _eventHandler) {
51
+ this._identity = _identity;
52
+ this._key = _key;
53
+ this._chain = _chain;
54
+ this._storage = _storage;
55
+ this._idpWindow = _idpWindow;
56
+ this._eventHandler = _eventHandler;
57
+ }
58
+ static async create(options = {}) {
59
+ var _a;
60
+ const storage = (_a = options.storage) !== null && _a !== void 0 ? _a : new LocalStorage('ic-');
61
+ let key = null;
62
+ if (options.identity) {
63
+ key = options.identity;
64
+ }
65
+ else {
66
+ const maybeIdentityStorage = await storage.get(KEY_LOCALSTORAGE_KEY);
67
+ if (maybeIdentityStorage) {
68
+ try {
69
+ key = Ed25519KeyIdentity.fromJSON(maybeIdentityStorage);
70
+ }
71
+ catch (e) {
72
+ // Ignore this, this means that the localStorage value isn't a valid Ed25519KeyIdentity
73
+ // serialization.
74
+ }
75
+ }
76
+ }
77
+ let identity = new AnonymousIdentity();
78
+ let chain = null;
79
+ if (key) {
80
+ try {
81
+ const chainStorage = await storage.get(KEY_LOCALSTORAGE_DELEGATION);
82
+ if (chainStorage) {
83
+ chain = DelegationChain.fromJSON(chainStorage);
84
+ // Verify that the delegation isn't expired.
85
+ if (!isDelegationValid(chain)) {
86
+ await _deleteStorage(storage);
87
+ key = null;
88
+ }
89
+ else {
90
+ identity = DelegationIdentity.fromDelegation(key, chain);
91
+ }
92
+ }
93
+ }
94
+ catch (e) {
95
+ console.error(e);
96
+ // If there was a problem loading the chain, delete the key.
97
+ await _deleteStorage(storage);
98
+ key = null;
99
+ }
100
+ }
101
+ return new this(identity, key, chain, storage);
102
+ }
103
+ _handleSuccess(message, onSuccess) {
104
+ var _a;
105
+ const delegations = message.delegations.map(signedDelegation => {
106
+ return {
107
+ delegation: new Delegation(signedDelegation.delegation.pubkey, signedDelegation.delegation.expiration, signedDelegation.delegation.targets),
108
+ signature: signedDelegation.signature.buffer,
109
+ };
110
+ });
111
+ const delegationChain = DelegationChain.fromDelegations(delegations, message.userPublicKey.buffer);
112
+ const key = this._key;
113
+ if (!key) {
114
+ return;
115
+ }
116
+ this._chain = delegationChain;
117
+ this._identity = DelegationIdentity.fromDelegation(key, this._chain);
118
+ (_a = this._idpWindow) === null || _a === void 0 ? void 0 : _a.close();
119
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
120
+ this._removeEventListener();
121
+ }
122
+ getIdentity() {
123
+ return this._identity;
124
+ }
125
+ async isAuthenticated() {
126
+ return !this.getIdentity().getPrincipal().isAnonymous() && this._chain !== null;
127
+ }
128
+ async login(options) {
129
+ var _a, _b, _c;
130
+ let key = this._key;
131
+ if (!key) {
132
+ // Create a new key (whether or not one was in storage).
133
+ key = Ed25519KeyIdentity.generate();
134
+ this._key = key;
135
+ await this._storage.set(KEY_LOCALSTORAGE_KEY, JSON.stringify(key));
136
+ }
137
+ // Create the URL of the IDP. (e.g. https://XXXX/#authorize)
138
+ const identityProviderUrl = new URL(((_a = options === null || options === void 0 ? void 0 : options.identityProvider) === null || _a === void 0 ? void 0 : _a.toString()) || IDENTITY_PROVIDER_DEFAULT);
139
+ // Set the correct hash if it isn't already set.
140
+ identityProviderUrl.hash = IDENTITY_PROVIDER_ENDPOINT;
141
+ // If `login` has been called previously, then close/remove any previous windows
142
+ // and event listeners.
143
+ (_b = this._idpWindow) === null || _b === void 0 ? void 0 : _b.close();
144
+ this._removeEventListener();
145
+ // Add an event listener to handle responses.
146
+ this._eventHandler = this._getEventHandler(identityProviderUrl, options);
147
+ window.addEventListener('message', this._eventHandler);
148
+ // Open a new window with the IDP provider.
149
+ this._idpWindow = (_c = window.open(identityProviderUrl.toString(), 'idpWindow')) !== null && _c !== void 0 ? _c : undefined;
150
+ }
151
+ _getEventHandler(identityProviderUrl, options) {
152
+ return async (event) => {
153
+ var _a, _b;
154
+ if (event.origin !== identityProviderUrl.origin) {
155
+ return;
156
+ }
157
+ const message = event.data;
158
+ switch (message.kind) {
159
+ case 'authorize-ready': {
160
+ // IDP is ready. Send a message to request authorization.
161
+ const request = {
162
+ kind: 'authorize-client',
163
+ sessionPublicKey: new Uint8Array((_a = this._key) === null || _a === void 0 ? void 0 : _a.getPublicKey().toDer()),
164
+ maxTimeToLive: options === null || options === void 0 ? void 0 : options.maxTimeToLive,
165
+ };
166
+ (_b = this._idpWindow) === null || _b === void 0 ? void 0 : _b.postMessage(request, identityProviderUrl.origin);
167
+ break;
168
+ }
169
+ case 'authorize-client-success':
170
+ // Create the delegation chain and store it.
171
+ try {
172
+ this._handleSuccess(message, options === null || options === void 0 ? void 0 : options.onSuccess);
173
+ // Setting the storage is moved out of _handleSuccess to make
174
+ // it a sync function. Having _handleSuccess as an async function
175
+ // messes up the jest tests for some reason.
176
+ if (this._chain) {
177
+ await this._storage.set(KEY_LOCALSTORAGE_DELEGATION, JSON.stringify(this._chain.toJSON()));
178
+ }
179
+ }
180
+ catch (err) {
181
+ this._handleFailure(err.message, options === null || options === void 0 ? void 0 : options.onError);
182
+ }
183
+ break;
184
+ case 'authorize-client-failure':
185
+ this._handleFailure(message.text, options === null || options === void 0 ? void 0 : options.onError);
186
+ break;
187
+ default:
188
+ break;
189
+ }
190
+ };
191
+ }
192
+ _handleFailure(errorMessage, onError) {
193
+ var _a;
194
+ (_a = this._idpWindow) === null || _a === void 0 ? void 0 : _a.close();
195
+ onError === null || onError === void 0 ? void 0 : onError(errorMessage);
196
+ this._removeEventListener();
197
+ }
198
+ _removeEventListener() {
199
+ if (this._eventHandler) {
200
+ window.removeEventListener('message', this._eventHandler);
201
+ }
202
+ this._eventHandler = undefined;
203
+ }
204
+ async logout(options = {}) {
205
+ _deleteStorage(this._storage);
206
+ // Reset this auth client to a non-authenticated state.
207
+ this._identity = new AnonymousIdentity();
208
+ this._key = null;
209
+ this._chain = null;
210
+ if (options.returnTo) {
211
+ try {
212
+ window.history.pushState({}, '', options.returnTo);
213
+ }
214
+ catch (e) {
215
+ window.location.href = options.returnTo;
216
+ }
217
+ }
218
+ }
219
+ }
220
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}