@konemono/nostr-login 1.15.4 → 1.15.5
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 +2 -2
- package/src/modules/AuthNostrService.ts +57 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konemono/nostr-login",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.5",
|
|
4
4
|
"description": "Extended fork of nostr-login with multi-relay support, QR scanner, and improved stability",
|
|
5
5
|
"main": "./dist/index.esm.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"tseep": "^1.2.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@konemono/nostr-login-components": "^1.4.
|
|
30
|
+
"@konemono/nostr-login-components": "^1.4.5",
|
|
31
31
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
32
32
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
33
33
|
"@rollup/plugin-terser": "^0.4.4",
|
|
@@ -96,6 +96,7 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
96
96
|
public cancelNostrConnect() {
|
|
97
97
|
console.log('cancelNostrConnect called');
|
|
98
98
|
this.releaseSigner();
|
|
99
|
+
this.resetNostrConnectKeys();
|
|
99
100
|
|
|
100
101
|
// readyCallbackのみ解放
|
|
101
102
|
this.resetAuth();
|
|
@@ -208,14 +209,35 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
208
209
|
this.onAuth('login', info);
|
|
209
210
|
}
|
|
210
211
|
|
|
212
|
+
// 接続成功後にkey/secretをリセット(次回のモーダル表示で新規生成される)
|
|
213
|
+
this.resetNostrConnectKeys();
|
|
214
|
+
|
|
211
215
|
console.log('[nostrConnect] Completed successfully');
|
|
212
216
|
return info;
|
|
213
217
|
}
|
|
214
218
|
|
|
215
|
-
public async createNostrConnect() {
|
|
216
|
-
this.
|
|
217
|
-
this.
|
|
219
|
+
public async createNostrConnect(relays: string[]) {
|
|
220
|
+
this.ensureNostrConnectKeys();
|
|
221
|
+
return this.buildNostrConnectUrl(relays);
|
|
222
|
+
}
|
|
218
223
|
|
|
224
|
+
/**
|
|
225
|
+
* key/secret が未生成なら新規生成する。既存なら再利用。
|
|
226
|
+
* モーダル表示中にリレーが変更されても key/secret は維持される。
|
|
227
|
+
*/
|
|
228
|
+
private ensureNostrConnectKeys() {
|
|
229
|
+
if (!this.nostrConnectKey) {
|
|
230
|
+
this.nostrConnectKey = generatePrivateKey();
|
|
231
|
+
}
|
|
232
|
+
if (!this.nostrConnectSecret) {
|
|
233
|
+
this.nostrConnectSecret = Array.from(crypto.getRandomValues(new Uint8Array(16)), b => b.toString(16).padStart(2, '0')).join('');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* 現在の key/secret を使って nostrconnect:// URL を構築する。
|
|
239
|
+
*/
|
|
240
|
+
private async buildNostrConnectUrl(relays: string[]): Promise<string> {
|
|
219
241
|
const pubkey = getPublicKey(hexToBytes(this.nostrConnectKey));
|
|
220
242
|
const meta = {
|
|
221
243
|
name: encodeURIComponent(document.location.host),
|
|
@@ -224,27 +246,34 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
224
246
|
perms: encodeURIComponent(this.params.optionsModal.perms || ''),
|
|
225
247
|
};
|
|
226
248
|
|
|
227
|
-
|
|
249
|
+
const relayParams = relays.map(r => `&relay=${encodeURIComponent(r)}`).join('');
|
|
250
|
+
return `nostrconnect://${pubkey}?image=${meta.icon}&url=${meta.url}&name=${meta.name}&perms=${meta.perms}&secret=${this.nostrConnectSecret}${relayParams}`;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* nostrconnect セッションをリセットし、key/secret を再生成可能にする。
|
|
255
|
+
*/
|
|
256
|
+
public resetNostrConnectKeys() {
|
|
257
|
+
this.nostrConnectKey = '';
|
|
258
|
+
this.nostrConnectSecret = '';
|
|
228
259
|
}
|
|
229
260
|
|
|
230
261
|
public async getNostrConnectServices(customRelays?: string[], onUpdate?: (apps: ConnectionString[]) => void): Promise<[string, ConnectionString[]]> {
|
|
231
|
-
const
|
|
262
|
+
const defaultRelays = customRelays && customRelays.length > 0 ? customRelays : DEFAULT_NIP46_RELAYS;
|
|
263
|
+
// ベースURLにリレーヒントを含める
|
|
264
|
+
const nostrconnect = await this.createNostrConnect(defaultRelays);
|
|
232
265
|
|
|
233
266
|
const apps: ConnectionString[] = NOSTRCONNECT_APPS.map(a => ({ ...a }));
|
|
234
|
-
const defaultRelays = customRelays && customRelays.length > 0 ? customRelays : DEFAULT_NIP46_RELAYS;
|
|
235
267
|
|
|
236
268
|
// Build initial list: https services are 'loading', others are immediately available
|
|
237
269
|
for (const a of apps) {
|
|
238
270
|
if (a.link.startsWith('https://')) {
|
|
239
271
|
a.available = 'loading';
|
|
240
|
-
//
|
|
241
|
-
|
|
242
|
-
a.link = nostrconnect + relayParams;
|
|
272
|
+
// nostrconnect URL にはすでにリレーヒントが含まれている
|
|
273
|
+
a.link = nostrconnect;
|
|
243
274
|
} else {
|
|
244
275
|
a.available = true;
|
|
245
|
-
|
|
246
|
-
const nc = nostrconnect + relayParams;
|
|
247
|
-
a.link = a.link.replace('<nostrconnect>', nc);
|
|
276
|
+
a.link = a.link.replace('<nostrconnect>', nostrconnect);
|
|
248
277
|
}
|
|
249
278
|
}
|
|
250
279
|
|
|
@@ -259,15 +288,15 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
259
288
|
try {
|
|
260
289
|
const info = await fetchNostrJson(domain);
|
|
261
290
|
const pubkey = info.names['_'];
|
|
262
|
-
let relays = defaultRelays;
|
|
263
291
|
const fetchedRelays = info.nip46[pubkey] as string[];
|
|
292
|
+
a.iframeUrl = info.nip46.iframe_url || '';
|
|
293
|
+
// サービス固有のリレーがあればURLを再構築
|
|
264
294
|
if (fetchedRelays && fetchedRelays.length && (!customRelays || customRelays.length === 0)) {
|
|
265
|
-
|
|
295
|
+
const serviceNostrconnect = this.replaceRelayHints(nostrconnect, fetchedRelays);
|
|
296
|
+
a.link = a.iframeUrl ? serviceNostrconnect : a.link;
|
|
297
|
+
} else {
|
|
298
|
+
a.link = a.iframeUrl ? nostrconnect : a.link;
|
|
266
299
|
}
|
|
267
|
-
a.iframeUrl = info.nip46.iframe_url || '';
|
|
268
|
-
const relayParams = relays.map(r => `&relay=${encodeURIComponent(r)}`).join('');
|
|
269
|
-
const nc = nostrconnect + relayParams;
|
|
270
|
-
a.link = a.iframeUrl ? nc : a.link;
|
|
271
300
|
a.available = true;
|
|
272
301
|
} catch (e) {
|
|
273
302
|
console.log('Service unavailable', domain, e);
|
|
@@ -278,11 +307,17 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
278
307
|
|
|
279
308
|
await Promise.all(fetchPromises);
|
|
280
309
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const nostrconnectWithRelays = nostrconnect + relayParams;
|
|
310
|
+
return [nostrconnect, apps];
|
|
311
|
+
}
|
|
284
312
|
|
|
285
|
-
|
|
313
|
+
private replaceRelayHints(nostrconnectUrl: string, newRelays: string[]): string {
|
|
314
|
+
// 既存のrelay=パラメータを除去して新しいリレーに置換
|
|
315
|
+
const url = new URL(nostrconnectUrl);
|
|
316
|
+
url.searchParams.delete('relay');
|
|
317
|
+
for (const r of newRelays) {
|
|
318
|
+
url.searchParams.append('relay', r);
|
|
319
|
+
}
|
|
320
|
+
return url.toString();
|
|
286
321
|
}
|
|
287
322
|
|
|
288
323
|
public async localSignup(name: string, sk?: string) {
|