@konemono/nostr-login 1.7.22 → 1.7.24
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.
- package/package.json +1 -1
- package/src/const/index.ts +1 -0
- package/src/iife-module.ts +7 -2
- package/src/index.ts +0 -7
- package/src/modules/AuthNostrService.ts +47 -204
- package/src/modules/BannerManager.ts +1 -9
- package/src/modules/ModalManager.ts +49 -56
- package/src/modules/Nip46.ts +115 -109
- package/src/modules/ProcessManager.ts +5 -47
- package/src/types.ts +2 -32
- package/src/utils/index.ts +15 -29
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { NostrLoginOptions, StartScreens, TypeModal } from '../types';
|
|
2
|
-
import { checkNip05, getBunkerUrl, getDarkMode, localStorageRemoveRecent, localStorageSetItem, prepareSignupRelays } from '../utils';
|
|
2
|
+
import { checkNip05, getBunkerUrl, getDarkMode, localStorageRemoveRecent, localStorageSetItem, prepareSignupRelays, localStorageGetItem } from '../utils';
|
|
3
3
|
import { AuthNostrService, NostrExtensionService, NostrParams } from '.';
|
|
4
4
|
import { EventEmitter } from 'tseep';
|
|
5
|
-
import { ConnectionString, Info, RecentType } from 'nostr-login-components';
|
|
5
|
+
import { ConnectionString, Info, RecentType } from 'nostr-login-components/dist/types/types';
|
|
6
6
|
import { nip19 } from 'nostr-tools';
|
|
7
7
|
import { setDarkMode } from '..';
|
|
8
8
|
|
|
9
|
+
const RELAY_STORAGE_KEY = '__nostrlogin_user_relays';
|
|
10
|
+
|
|
9
11
|
class ModalManager extends EventEmitter {
|
|
10
12
|
private modal: TypeModal | null = null;
|
|
11
13
|
private params: NostrParams;
|
|
@@ -23,6 +25,18 @@ class ModalManager extends EventEmitter {
|
|
|
23
25
|
this.authNostrService = authNostrService;
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
private getUserRelays(): string[] {
|
|
29
|
+
const stored = localStorageGetItem(RELAY_STORAGE_KEY);
|
|
30
|
+
if (stored && Array.isArray(stored)) {
|
|
31
|
+
return stored;
|
|
32
|
+
}
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private saveUserRelays(relays: string[]) {
|
|
37
|
+
localStorageSetItem(RELAY_STORAGE_KEY, JSON.stringify(relays));
|
|
38
|
+
}
|
|
39
|
+
|
|
26
40
|
public async waitReady() {
|
|
27
41
|
if (this.launcherPromise) {
|
|
28
42
|
try {
|
|
@@ -34,10 +48,8 @@ class ModalManager extends EventEmitter {
|
|
|
34
48
|
|
|
35
49
|
public async launch(opt: NostrLoginOptions) {
|
|
36
50
|
console.log('nostr-login launch', opt);
|
|
37
|
-
// mutex
|
|
38
51
|
if (this.launcherPromise) await this.waitReady();
|
|
39
52
|
|
|
40
|
-
// hmm?!
|
|
41
53
|
if (this.authNostrService.isAuthing()) this.authNostrService.resetAuth();
|
|
42
54
|
|
|
43
55
|
this.opt = opt;
|
|
@@ -61,7 +73,6 @@ class ModalManager extends EventEmitter {
|
|
|
61
73
|
this.modal.setAttribute('bunkers', opt.bunkers);
|
|
62
74
|
} else {
|
|
63
75
|
let bunkers = 'nsec.app,highlighter.com';
|
|
64
|
-
// if (opt.dev) bunkers += ',new.nsec.app';
|
|
65
76
|
this.modal.setAttribute('bunkers', bunkers);
|
|
66
77
|
}
|
|
67
78
|
|
|
@@ -91,6 +102,11 @@ class ModalManager extends EventEmitter {
|
|
|
91
102
|
this.modal.isLoadingExtension = false;
|
|
92
103
|
this.modal.isLoading = false;
|
|
93
104
|
|
|
105
|
+
const userRelays = this.getUserRelays();
|
|
106
|
+
if (userRelays.length > 0) {
|
|
107
|
+
this.params.optionsModal.connectRelays = userRelays;
|
|
108
|
+
}
|
|
109
|
+
|
|
94
110
|
[this.modal.connectionString, this.modal.connectionStringServices] = await this.authNostrService.getNostrConnectServices();
|
|
95
111
|
|
|
96
112
|
dialog.appendChild(this.modal);
|
|
@@ -100,21 +116,11 @@ class ModalManager extends EventEmitter {
|
|
|
100
116
|
|
|
101
117
|
this.launcherPromise = new Promise<void>((ok, err) => {
|
|
102
118
|
dialog.addEventListener('close', () => {
|
|
103
|
-
// noop if already resolved
|
|
104
119
|
err(new Error('Closed'));
|
|
105
120
|
|
|
106
121
|
this.authNostrService.resetAuth();
|
|
107
122
|
|
|
108
123
|
if (this.modal) {
|
|
109
|
-
// it's reset on modal creation
|
|
110
|
-
// // reset state
|
|
111
|
-
// this.modal.isLoading = false;
|
|
112
|
-
// this.modal.authUrl = '';
|
|
113
|
-
// this.modal.iframeUrl = '';
|
|
114
|
-
// this.modal.error = '';
|
|
115
|
-
// this.modal.isLoadingExtension = false;
|
|
116
|
-
|
|
117
|
-
// drop it
|
|
118
124
|
// @ts-ignore
|
|
119
125
|
document.body.removeChild(this.modal.parentNode);
|
|
120
126
|
this.modal = null;
|
|
@@ -157,20 +163,16 @@ class ModalManager extends EventEmitter {
|
|
|
157
163
|
|
|
158
164
|
const login = async (name: string, domain?: string) => {
|
|
159
165
|
await exec(async () => {
|
|
160
|
-
// convert name to bunker url
|
|
161
166
|
const bunkerUrl = await getBunkerUrl(name, this.params.optionsModal);
|
|
162
167
|
|
|
163
|
-
// connect to bunker by url
|
|
164
168
|
await this.authNostrService.authNip46('login', { name, bunkerUrl, domain });
|
|
165
169
|
});
|
|
166
170
|
};
|
|
167
171
|
|
|
168
172
|
const signup = async (name: string) => {
|
|
169
173
|
await exec(async () => {
|
|
170
|
-
// create acc on service and get bunker url
|
|
171
174
|
const { bunkerUrl, sk } = await this.authNostrService.createAccount(name);
|
|
172
175
|
|
|
173
|
-
// connect to bunker by url
|
|
174
176
|
await this.authNostrService.authNip46('signup', { name, bunkerUrl, sk });
|
|
175
177
|
});
|
|
176
178
|
};
|
|
@@ -190,7 +192,6 @@ class ModalManager extends EventEmitter {
|
|
|
190
192
|
cs.link = this.authNostrService.prepareImportUrl(cs.link);
|
|
191
193
|
|
|
192
194
|
if (this.modal && iframeUrl) {
|
|
193
|
-
// we pass the link down to iframe so it could open it
|
|
194
195
|
this.modal.authUrl = cs.link;
|
|
195
196
|
this.modal.iframeUrl = iframeUrl;
|
|
196
197
|
this.modal.isLoading = false;
|
|
@@ -208,7 +209,6 @@ class ModalManager extends EventEmitter {
|
|
|
208
209
|
|
|
209
210
|
if (this.modal) {
|
|
210
211
|
if (iframeUrl) {
|
|
211
|
-
// we pass the link down to iframe so it could open it
|
|
212
212
|
this.modal.authUrl = link;
|
|
213
213
|
this.modal.iframeUrl = iframeUrl;
|
|
214
214
|
this.modal.isLoading = false;
|
|
@@ -239,8 +239,6 @@ class ModalManager extends EventEmitter {
|
|
|
239
239
|
.charAt(0)
|
|
240
240
|
.toUpperCase() + self.hostname.slice(1);
|
|
241
241
|
const relays = prepareSignupRelays(this.params.optionsModal.signupRelays);
|
|
242
|
-
// const url = `https://start.njump.me/?an=${name}&at=popup&ac=${window.location.href}&s=${this.opt!.followNpubs || ''}&arr=${relays}&awr=${relays}`;
|
|
243
|
-
// console.log('njump url', url);
|
|
244
242
|
|
|
245
243
|
this.modal!.njumpIframe = `
|
|
246
244
|
<html><body>
|
|
@@ -248,18 +246,15 @@ class ModalManager extends EventEmitter {
|
|
|
248
246
|
<script>
|
|
249
247
|
new NstartModal({
|
|
250
248
|
baseUrl: 'https://start.njump.me',
|
|
251
|
-
// Required parameters
|
|
252
249
|
an: '${name}',
|
|
253
|
-
// Optional parameters
|
|
254
250
|
s: [${this.opt!.followNpubs ? `'${this.opt!.followNpubs}'` : ''}],
|
|
255
|
-
afb: false,
|
|
256
|
-
asb: false,
|
|
257
|
-
aan: false,
|
|
258
|
-
aac: true,
|
|
259
|
-
ahc: true,
|
|
260
|
-
arr: ${JSON.stringify(relays)},
|
|
261
|
-
awr: ${JSON.stringify(relays)},
|
|
262
|
-
// Callbacks
|
|
251
|
+
afb: false,
|
|
252
|
+
asb: false,
|
|
253
|
+
aan: false,
|
|
254
|
+
aac: true,
|
|
255
|
+
ahc: true,
|
|
256
|
+
arr: ${JSON.stringify(relays)},
|
|
257
|
+
awr: ${JSON.stringify(relays)},
|
|
263
258
|
onComplete: (result) => {
|
|
264
259
|
console.log('Login token:', result.nostrLogin);
|
|
265
260
|
window.parent.location.href='${window.location.href}#nostr-login='+result.nostrLogin;
|
|
@@ -270,11 +265,10 @@ class ModalManager extends EventEmitter {
|
|
|
270
265
|
}).open();
|
|
271
266
|
</script>
|
|
272
267
|
</body></html>
|
|
273
|
-
`.replaceAll('&', '&');
|
|
268
|
+
`.replaceAll('&', '&');
|
|
274
269
|
|
|
275
270
|
return new Promise((ok, err) => {
|
|
276
271
|
const process = async (nsecOrBunker: string) => {
|
|
277
|
-
// process the returned value
|
|
278
272
|
console.log('nsecOrBunker', nsecOrBunker);
|
|
279
273
|
if (nsecOrBunker.startsWith('nsec1')) {
|
|
280
274
|
let decoded;
|
|
@@ -300,7 +294,6 @@ class ModalManager extends EventEmitter {
|
|
|
300
294
|
if (window.location.hash.startsWith('#nostr-login=')) {
|
|
301
295
|
const nsecOrBunker = window.location.hash.split('#nostr-login=')[1];
|
|
302
296
|
|
|
303
|
-
// clear hash from history
|
|
304
297
|
const url = new URL(window.location.toString());
|
|
305
298
|
url.hash = '';
|
|
306
299
|
window.history.replaceState({}, '', url.toString());
|
|
@@ -309,9 +302,6 @@ class ModalManager extends EventEmitter {
|
|
|
309
302
|
}
|
|
310
303
|
};
|
|
311
304
|
|
|
312
|
-
// // use random 'target' to make sure window.opener is
|
|
313
|
-
// // accessible to the popup
|
|
314
|
-
// window.open(url, '' + Date.now(), 'popup=true,width=600,height=950');
|
|
315
305
|
window.addEventListener('hashchange', onOpen);
|
|
316
306
|
});
|
|
317
307
|
});
|
|
@@ -359,7 +349,6 @@ class ModalManager extends EventEmitter {
|
|
|
359
349
|
});
|
|
360
350
|
|
|
361
351
|
this.modal.addEventListener('nlNostrConnectDefault', () => {
|
|
362
|
-
// dedup the calls
|
|
363
352
|
if (!this.authNostrService.isAuthing()) nostrConnect();
|
|
364
353
|
});
|
|
365
354
|
|
|
@@ -368,18 +357,30 @@ class ModalManager extends EventEmitter {
|
|
|
368
357
|
this.authNostrService.cancelNostrConnect();
|
|
369
358
|
});
|
|
370
359
|
|
|
360
|
+
this.modal.addEventListener('nlSaveUserRelays', (event: any) => {
|
|
361
|
+
const relays = event.detail as string[];
|
|
362
|
+
console.log('nlSaveUserRelays', relays);
|
|
363
|
+
this.saveUserRelays(relays);
|
|
364
|
+
this.params.optionsModal.connectRelays = relays;
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
this.modal.addEventListener('nlGetUserRelays', () => {
|
|
368
|
+
const relays = this.getUserRelays();
|
|
369
|
+
console.log('nlGetUserRelays', relays);
|
|
370
|
+
if (this.modal) {
|
|
371
|
+
this.modal.dispatchEvent(
|
|
372
|
+
new CustomEvent('nlUserRelaysReply', {
|
|
373
|
+
detail: relays,
|
|
374
|
+
}),
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
|
|
371
379
|
this.modal.addEventListener('nlSwitchAccount', (event: any) => {
|
|
372
380
|
const eventInfo: Info = event.detail as Info;
|
|
373
381
|
|
|
374
382
|
this.emit('onSwitchAccount', eventInfo);
|
|
375
383
|
|
|
376
|
-
// wait a bit, if dialog closes before
|
|
377
|
-
// switching finishes then launched promise rejects
|
|
378
|
-
|
|
379
|
-
// FIXME this calls resetAuth which then prevents
|
|
380
|
-
// endAuth from getting properly called. 300 is not
|
|
381
|
-
// enough to init iframe, so there should be a
|
|
382
|
-
// feedback from switchAccount here
|
|
383
384
|
setTimeout(() => dialog.close(), 300);
|
|
384
385
|
});
|
|
385
386
|
|
|
@@ -426,7 +427,7 @@ class ModalManager extends EventEmitter {
|
|
|
426
427
|
else throw new Error('Bad npub');
|
|
427
428
|
} else if (nameNpub.trim().length === 64) {
|
|
428
429
|
pubkey = nameNpub.trim();
|
|
429
|
-
nip19.npubEncode(pubkey);
|
|
430
|
+
nip19.npubEncode(pubkey);
|
|
430
431
|
}
|
|
431
432
|
return pubkey;
|
|
432
433
|
};
|
|
@@ -466,13 +467,10 @@ class ModalManager extends EventEmitter {
|
|
|
466
467
|
throw new Error('Failed to send DM');
|
|
467
468
|
}
|
|
468
469
|
|
|
469
|
-
// switch to 'enter code' mode
|
|
470
470
|
this.modal.isOTP = true;
|
|
471
471
|
|
|
472
|
-
// remember for code handler below
|
|
473
472
|
otpPubkey = pubkey;
|
|
474
473
|
|
|
475
|
-
// spinner off
|
|
476
474
|
this.modal.isLoading = false;
|
|
477
475
|
},
|
|
478
476
|
{ start: true },
|
|
@@ -529,8 +527,6 @@ class ModalManager extends EventEmitter {
|
|
|
529
527
|
this.modal.isLoading = false;
|
|
530
528
|
}
|
|
531
529
|
|
|
532
|
-
// this.authNostrService.cancelListenNostrConnect();
|
|
533
|
-
|
|
534
530
|
dialog.close();
|
|
535
531
|
err(new Error('Cancelled'));
|
|
536
532
|
};
|
|
@@ -555,9 +551,6 @@ class ModalManager extends EventEmitter {
|
|
|
555
551
|
}
|
|
556
552
|
|
|
557
553
|
public async showIframeUrl(url: string) {
|
|
558
|
-
// make sure we consume the previous promise,
|
|
559
|
-
// otherwise launch will start await-ing
|
|
560
|
-
// before modal is created and setting iframeUrl will fail
|
|
561
554
|
await this.waitReady();
|
|
562
555
|
|
|
563
556
|
this.launch({
|