ns-auth-sdk 1.2.6 → 1.3.0

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,528 @@
1
+ const require_index = require('./index.cjs');
2
+ let rx_nostr_crypto = require("rx-nostr-crypto");
3
+
4
+ //#region src/utils/utils.ts
5
+ /**
6
+ * @packageDocumentation
7
+ */
8
+ /**
9
+ * @param bytes
10
+ * @returns
11
+ */
12
+ function bytesToHex(bytes) {
13
+ const key = "0123456789abcdef";
14
+ let hex = "";
15
+ for (let i = 0; i < bytes.length; i++) {
16
+ const firstNibble = bytes[i] >> 4;
17
+ const secondNibble = bytes[i] & 15;
18
+ hex += key[firstNibble] + key[secondNibble];
19
+ }
20
+ return hex;
21
+ }
22
+ /**
23
+ * @param hex
24
+ * @returns
25
+ */
26
+ function hexToBytes(hex) {
27
+ const key = "0123456789abcdef";
28
+ const bytes = [];
29
+ let currentByte = 0;
30
+ let highNibble = true;
31
+ for (let i = 0; i < hex.length; i++) {
32
+ const charValue = key.indexOf(hex[i].toLowerCase());
33
+ if (charValue === -1) continue;
34
+ if (highNibble) {
35
+ currentByte = charValue << 4;
36
+ highNibble = false;
37
+ } else {
38
+ currentByte += charValue;
39
+ bytes.push(currentByte);
40
+ highNibble = true;
41
+ }
42
+ }
43
+ return new Uint8Array(bytes);
44
+ }
45
+
46
+ //#endregion
47
+ //#region src/utils/key-cache.ts
48
+ /**
49
+ * Key cache manager for managing temporary secret keys
50
+ */
51
+ var KeyCache = class {
52
+ #cachedEntry = null;
53
+ #expiryTimer = null;
54
+ #cacheOptions = {
55
+ enabled: false,
56
+ timeoutMs: 300 * 1e3
57
+ };
58
+ /**
59
+ * KeyCache
60
+ * @param options
61
+ */
62
+ constructor(options) {
63
+ if (options) this.#cacheOptions = {
64
+ ...this.#cacheOptions,
65
+ ...options
66
+ };
67
+ }
68
+ /**
69
+ * @param options
70
+ */
71
+ setCacheOptions(options) {
72
+ if (Object.keys(options).length > 0 && this.#cachedEntry !== null) this.clearAllCachedKeys();
73
+ this.#cacheOptions = {
74
+ ...this.#cacheOptions,
75
+ ...options
76
+ };
77
+ }
78
+ getCacheOptions() {
79
+ return { ...this.#cacheOptions };
80
+ }
81
+ isEnabled() {
82
+ return this.#cacheOptions.enabled;
83
+ }
84
+ /**
85
+ * @param credentialId
86
+ * @param sk
87
+ */
88
+ setKey(credentialId, sk) {
89
+ if (!this.#cacheOptions.enabled) return;
90
+ const id = typeof credentialId === "string" ? credentialId : bytesToHex(credentialId);
91
+ const timeout = this.#cacheOptions.timeoutMs !== void 0 ? this.#cacheOptions.timeoutMs : 300 * 1e3;
92
+ const expireAt = Date.now() + timeout;
93
+ this.#clearCachedEntry();
94
+ this.#cachedEntry = {
95
+ id,
96
+ sk: new Uint8Array(sk),
97
+ expireAt
98
+ };
99
+ try {
100
+ this.#scheduleExpiry();
101
+ } catch (error) {
102
+ this.#clearCachedEntry();
103
+ throw error;
104
+ }
105
+ }
106
+ /**
107
+ * @param credentialId
108
+ * @returns undefined
109
+ */
110
+ getKey(credentialId) {
111
+ if (!this.#cacheOptions.enabled) return void 0;
112
+ const id = typeof credentialId === "string" ? credentialId : bytesToHex(credentialId);
113
+ return this.#getCachedKeyIfValid(id);
114
+ }
115
+ /**
116
+ * @param credentialId
117
+ */
118
+ clearCachedKey(credentialId) {
119
+ const id = typeof credentialId === "string" ? credentialId : bytesToHex(credentialId);
120
+ if (this.#cachedEntry && this.#cachedEntry.id === id) this.#clearCachedEntry();
121
+ }
122
+ clearAllCachedKeys() {
123
+ this.#clearCachedEntry();
124
+ }
125
+ /**
126
+ * @param credentialId
127
+ * @returns undefined
128
+ */
129
+ #getCachedKeyIfValid(credentialId) {
130
+ if (!this.#cachedEntry || this.#cachedEntry.id !== credentialId) return;
131
+ if (Date.now() < this.#cachedEntry.expireAt) return this.#cachedEntry.sk;
132
+ this.#clearCachedEntry();
133
+ }
134
+ #clearCachedEntry() {
135
+ if (this.#cachedEntry) {
136
+ this.#clearKey(this.#cachedEntry.sk);
137
+ this.#cachedEntry = null;
138
+ }
139
+ if (this.#expiryTimer) {
140
+ clearTimeout(this.#expiryTimer);
141
+ this.#expiryTimer = null;
142
+ }
143
+ }
144
+ #scheduleExpiry() {
145
+ if (!this.#cachedEntry) return;
146
+ const now = Date.now();
147
+ const timeToExpiry = this.#cachedEntry.expireAt - now;
148
+ if (timeToExpiry <= 0) {
149
+ this.#clearCachedEntry();
150
+ return;
151
+ }
152
+ this.#expiryTimer = setTimeout(() => {
153
+ this.#clearCachedEntry();
154
+ }, timeToExpiry + 1);
155
+ }
156
+ /**
157
+ * @param key
158
+ */
159
+ #clearKey(key) {
160
+ key?.fill?.(0);
161
+ }
162
+ };
163
+
164
+ //#endregion
165
+ //#region src/utils/prf-handler.ts
166
+ const PRF_EVAL_INPUT = new TextEncoder().encode("nostr-pwk");
167
+ /**
168
+ * @returns PRF
169
+ */
170
+ async function isPrfSupported() {
171
+ try {
172
+ const response = await navigator.credentials.get({ publicKey: {
173
+ challenge: crypto.getRandomValues(new Uint8Array(32)),
174
+ allowCredentials: [],
175
+ userVerification: "required",
176
+ extensions: { prf: { eval: { first: PRF_EVAL_INPUT } } }
177
+ } });
178
+ if (!response) return false;
179
+ return !!response.getClientExtensionResults()?.prf?.results?.first;
180
+ } catch {
181
+ return false;
182
+ }
183
+ }
184
+ /**
185
+ * @param options
186
+ * @returns Credential
187
+ */
188
+ async function createPasskey(options = {}) {
189
+ const rpName = options.rp?.name || (typeof location !== "undefined" ? location.host : "Nosskey");
190
+ const rpId = options.rp?.id;
191
+ const userName = options.user?.name || "user@example.com";
192
+ const userDisplayName = options.user?.displayName || "Nosskey user";
193
+ const credentialCreationOptions = { publicKey: {
194
+ rp: {
195
+ name: rpName,
196
+ id: rpId
197
+ },
198
+ user: {
199
+ id: crypto.getRandomValues(new Uint8Array(16)),
200
+ name: userName,
201
+ displayName: userDisplayName
202
+ },
203
+ pubKeyCredParams: options.pubKeyCredParams || [{
204
+ type: "public-key",
205
+ alg: -7
206
+ }],
207
+ authenticatorSelection: options.authenticatorSelection || {
208
+ residentKey: "required",
209
+ userVerification: "required"
210
+ },
211
+ challenge: crypto.getRandomValues(new Uint8Array(32)),
212
+ extensions: options.extensions || { prf: {} }
213
+ } };
214
+ const cred = await navigator.credentials.create(credentialCreationOptions);
215
+ return new Uint8Array(cred.rawId);
216
+ }
217
+ /**
218
+ * ID
219
+ * @param credentialId
220
+ * @param options PRF(rpId、timeout、userVerification)
221
+ * @returns PRF credentialID
222
+ */
223
+ async function getPrfSecret(credentialId, options) {
224
+ const allowCredentials = credentialId ? [{
225
+ type: "public-key",
226
+ id: credentialId
227
+ }] : [];
228
+ const requestOptions = {
229
+ challenge: crypto.getRandomValues(new Uint8Array(32)),
230
+ allowCredentials,
231
+ userVerification: options?.userVerification || "required",
232
+ extensions: { prf: { eval: { first: PRF_EVAL_INPUT } } }
233
+ };
234
+ if (options?.rpId) requestOptions.rpId = options.rpId;
235
+ if (options?.timeout) requestOptions.timeout = options.timeout;
236
+ const response = await navigator.credentials.get({ publicKey: requestOptions });
237
+ if (!response) throw new Error("Authentication failed");
238
+ const secret = response.getClientExtensionResults()?.prf?.results?.first;
239
+ if (!secret) throw new Error("PRF secret not available");
240
+ const responseId = new Uint8Array(response.rawId);
241
+ return {
242
+ secret: new Uint8Array(secret),
243
+ id: responseId
244
+ };
245
+ }
246
+
247
+ //#endregion
248
+ //#region src/utils/nosskey.ts
249
+ /**
250
+ * Nosskey class for Passkey-Derived Nostr Identity
251
+ * @packageDocumentation
252
+ */
253
+ const STANDARD_SALT = "6e6f7374722d6b6579";
254
+ /**
255
+ * Nosskey - Passkey-Derived Nostr Keys
256
+ */
257
+ var NosskeyManager = class {
258
+ #keyCache;
259
+ #currentKeyInfo = null;
260
+ #storageOptions = {
261
+ enabled: true,
262
+ storageKey: "nosskey_keyinfo"
263
+ };
264
+ #prfOptions = {};
265
+ /**
266
+ * NosskeyManager
267
+ * @param options
268
+ */
269
+ constructor(options) {
270
+ this.#keyCache = new KeyCache(options?.cacheOptions);
271
+ if (options?.storageOptions) this.#storageOptions = {
272
+ ...this.#storageOptions,
273
+ ...options.storageOptions
274
+ };
275
+ const userVerification = options?.prfOptions?.userVerification ?? "required";
276
+ if (options?.prfOptions) this.#prfOptions = {
277
+ ...options.prfOptions,
278
+ userVerification
279
+ };
280
+ else this.#prfOptions = { userVerification };
281
+ if (this.#storageOptions.enabled) {
282
+ const loadedKeyInfo = this.#loadKeyInfoFromStorage();
283
+ if (loadedKeyInfo) this.#currentKeyInfo = loadedKeyInfo;
284
+ }
285
+ }
286
+ /**
287
+ * NostrKeyInfo
288
+ * @param options
289
+ */
290
+ setStorageOptions(options) {
291
+ this.#storageOptions = {
292
+ ...this.#storageOptions,
293
+ ...options
294
+ };
295
+ if (options.enabled === false) this.clearStoredKeyInfo();
296
+ }
297
+ /**
298
+ * NostrKeyInfo
299
+ */
300
+ getStorageOptions() {
301
+ return { ...this.#storageOptions };
302
+ }
303
+ /**
304
+ * NostrKeyInfo
305
+ * @param keyInfo NostrKeyInfo
306
+ */
307
+ setCurrentKeyInfo(keyInfo) {
308
+ this.#currentKeyInfo = keyInfo;
309
+ if (this.#storageOptions.enabled) this.#saveKeyInfoToStorage(keyInfo);
310
+ }
311
+ /**
312
+ * NostrKeyInfo
313
+ */
314
+ getCurrentKeyInfo() {
315
+ if (!this.#currentKeyInfo && this.#storageOptions.enabled) this.#currentKeyInfo = this.#loadKeyInfoFromStorage();
316
+ return this.#currentKeyInfo;
317
+ }
318
+ /**
319
+ * NostrKeyInfo
320
+ * @returns NostrKeyInfo
321
+ */
322
+ hasKeyInfo() {
323
+ if (this.#currentKeyInfo) return true;
324
+ if (this.#storageOptions.enabled) {
325
+ const loadedKeyInfo = this.#loadKeyInfoFromStorage();
326
+ if (loadedKeyInfo) {
327
+ this.#currentKeyInfo = loadedKeyInfo;
328
+ return true;
329
+ }
330
+ }
331
+ return false;
332
+ }
333
+ /**
334
+ * NostrKeyInfo
335
+ * @param keyInfo NostrKeyInfo
336
+ */
337
+ async #saveKeyInfoToStorage(keyInfo) {
338
+ if (!this.#storageOptions.enabled) return;
339
+ const storage = this.#storageOptions.storage || (typeof localStorage !== "undefined" ? localStorage : null);
340
+ if (!storage) return;
341
+ const key = this.#storageOptions.storageKey || "nosskey_keyinfo";
342
+ storage.setItem(key, JSON.stringify(keyInfo));
343
+ }
344
+ /**
345
+ * NostrKeyInfo
346
+ */
347
+ #loadKeyInfoFromStorage() {
348
+ if (!this.#storageOptions.enabled) return null;
349
+ const storage = this.#storageOptions.storage || (typeof localStorage !== "undefined" ? localStorage : null);
350
+ if (!storage) return null;
351
+ const key = this.#storageOptions.storageKey || "nosskey_keyinfo";
352
+ const data = storage.getItem(key);
353
+ if (!data) return null;
354
+ try {
355
+ return JSON.parse(data);
356
+ } catch (e) {
357
+ console.error("Failed to parse stored NostrKeyInfo", e);
358
+ return null;
359
+ }
360
+ }
361
+ /**
362
+ * NostrKeyInfo
363
+ */
364
+ clearStoredKeyInfo() {
365
+ const storage = this.#storageOptions.storage || (typeof localStorage !== "undefined" ? localStorage : null);
366
+ if (!storage) return;
367
+ const key = this.#storageOptions.storageKey || "nosskey_keyinfo";
368
+ storage.removeItem(key);
369
+ this.#currentKeyInfo = null;
370
+ }
371
+ /**
372
+ * NIP-07
373
+ * NostrKeyInfo
374
+ */
375
+ async getPublicKey() {
376
+ const keyInfo = this.getCurrentKeyInfo();
377
+ if (!keyInfo) throw new Error("No current NostrKeyInfo set");
378
+ return keyInfo.pubkey;
379
+ }
380
+ /**
381
+ * NIP-07
382
+ * NostrKeyInfo
383
+ * @param event Nostr
384
+ */
385
+ async signEvent(event) {
386
+ const keyInfo = this.getCurrentKeyInfo();
387
+ if (!keyInfo) throw new Error("No current NostrKeyInfo set");
388
+ return this.signEventWithKeyInfo(event, keyInfo);
389
+ }
390
+ /**
391
+ * @param options
392
+ */
393
+ setCacheOptions(options) {
394
+ this.#keyCache.setCacheOptions(options);
395
+ }
396
+ getCacheOptions() {
397
+ return this.#keyCache.getCacheOptions();
398
+ }
399
+ /**
400
+ * @param credentialId
401
+ */
402
+ clearCachedKey(credentialId) {
403
+ this.#keyCache.clearCachedKey(credentialId);
404
+ }
405
+ clearAllCachedKeys() {
406
+ this.#keyCache.clearAllCachedKeys();
407
+ }
408
+ /**
409
+ * @param options
410
+ * @returns Credential
411
+ */
412
+ async createPasskey(options = {}) {
413
+ return createPasskey({
414
+ rp: {
415
+ id: this.#prfOptions.rpId,
416
+ name: this.#prfOptions.rpId
417
+ },
418
+ authenticatorSelection: { userVerification: this.#prfOptions.userVerification },
419
+ ...options
420
+ });
421
+ }
422
+ /**
423
+ * PRF NostrKeyInfo
424
+ * @param credentialId
425
+ * @param options
426
+ */
427
+ async createNostrKey(credentialId, options = {}) {
428
+ const { secret: sk, id: responseId } = await getPrfSecret(credentialId, this.#prfOptions);
429
+ if (sk.every((byte) => byte === 0)) throw new Error("Invalid PRF output: all zeros");
430
+ const publicKey = await (0, rx_nostr_crypto.seckeySigner)(bytesToHex(sk)).getPublicKey();
431
+ return {
432
+ credentialId: bytesToHex(credentialId || responseId),
433
+ pubkey: publicKey,
434
+ salt: STANDARD_SALT,
435
+ ...options.username && { username: options.username }
436
+ };
437
+ }
438
+ /**
439
+ * @param event Nostr
440
+ * @param keyInfo NostrKeyInfo
441
+ * @param options
442
+ */
443
+ async signEventWithKeyInfo(event, keyInfo, options = {}) {
444
+ const { clearMemory = true, tags } = options;
445
+ const shouldUseCache = this.#keyCache.isEnabled();
446
+ let sk;
447
+ if (shouldUseCache) sk = this.#keyCache.getKey(keyInfo.credentialId);
448
+ if (!sk) {
449
+ const { secret: prfSecret } = await getPrfSecret(hexToBytes(keyInfo.credentialId), this.#prfOptions);
450
+ sk = prfSecret;
451
+ if (shouldUseCache) this.#keyCache.setKey(keyInfo.credentialId, sk);
452
+ }
453
+ const signedEvent = await (0, rx_nostr_crypto.seckeySigner)(bytesToHex(sk), { tags }).signEvent(event);
454
+ if (!shouldUseCache && clearMemory) this.#clearKey(sk);
455
+ return signedEvent;
456
+ }
457
+ /**
458
+ * @param keyInfo NostrKeyInfo
459
+ * @param credentialId NostrKeyInfoのcredentialId
460
+ * @param options
461
+ * @returns
462
+ */
463
+ async exportNostrKey(keyInfo, credentialId) {
464
+ let usedCredentialId = credentialId;
465
+ if (!usedCredentialId && keyInfo.credentialId) usedCredentialId = hexToBytes(keyInfo.credentialId);
466
+ const { secret: sk } = await getPrfSecret(usedCredentialId, this.#prfOptions);
467
+ return bytesToHex(sk);
468
+ }
469
+ /**
470
+ * PRF
471
+ */
472
+ async isPrfSupported() {
473
+ return isPrfSupported();
474
+ }
475
+ /**
476
+ * @param key
477
+ */
478
+ #clearKey(key) {
479
+ key?.fill?.(0);
480
+ }
481
+ };
482
+
483
+ //#endregion
484
+ //#region src/utils/crypto-utils.ts
485
+ /**
486
+ * Cryptographic utilities for Nosskey
487
+ * @packageDocumentation
488
+ */
489
+ const INFO_BYTES = new TextEncoder().encode("nostr-pwk");
490
+
491
+ //#endregion
492
+ Object.defineProperty(exports, 'NosskeyManager', {
493
+ enumerable: true,
494
+ get: function () {
495
+ return NosskeyManager;
496
+ }
497
+ });
498
+ Object.defineProperty(exports, 'bytesToHex', {
499
+ enumerable: true,
500
+ get: function () {
501
+ return bytesToHex;
502
+ }
503
+ });
504
+ Object.defineProperty(exports, 'createPasskey', {
505
+ enumerable: true,
506
+ get: function () {
507
+ return createPasskey;
508
+ }
509
+ });
510
+ Object.defineProperty(exports, 'getPrfSecret', {
511
+ enumerable: true,
512
+ get: function () {
513
+ return getPrfSecret;
514
+ }
515
+ });
516
+ Object.defineProperty(exports, 'hexToBytes', {
517
+ enumerable: true,
518
+ get: function () {
519
+ return hexToBytes;
520
+ }
521
+ });
522
+ Object.defineProperty(exports, 'isPrfSupported', {
523
+ enumerable: true,
524
+ get: function () {
525
+ return isPrfSupported;
526
+ }
527
+ });
528
+ //# sourceMappingURL=utils-CxLeFzNn.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-CxLeFzNn.cjs","names":["#cacheOptions","#cachedEntry","#clearCachedEntry","#scheduleExpiry","#getCachedKeyIfValid","#clearKey","#expiryTimer","#keyCache","#storageOptions","#prfOptions","#loadKeyInfoFromStorage","#currentKeyInfo","#saveKeyInfoToStorage","#clearKey"],"sources":["../src/utils/utils.ts","../src/utils/key-cache.ts","../src/utils/prf-handler.ts","../src/utils/nosskey.ts","../src/utils/crypto-utils.ts"],"sourcesContent":["/**\n * @packageDocumentation\n */\n\n/**\n * @param bytes\n * @returns\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n const key = '0123456789abcdef';\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n const firstNibble = bytes[i] >> 4;\n const secondNibble = bytes[i] & 15;\n hex += key[firstNibble] + key[secondNibble];\n }\n return hex;\n}\n\n/**\n * @param hex\n * @returns\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const key = '0123456789abcdef';\n const bytes = [];\n let currentByte = 0;\n let highNibble = true;\n\n for (let i = 0; i < hex.length; i++) {\n const charValue = key.indexOf(hex[i].toLowerCase());\n if (charValue === -1) continue;\n\n if (highNibble) {\n currentByte = charValue << 4;\n highNibble = false;\n } else {\n currentByte += charValue;\n bytes.push(currentByte);\n highNibble = true;\n }\n }\n\n return new Uint8Array(bytes);\n}\n","/**\n * Key cache management for Nosskey\n * @packageDocumentation\n */\n\nimport type { KeyCacheOptions } from './types.js';\nimport { bytesToHex } from './utils.js';\n\n/**\n * Key cache entry with expiration time\n */\ninterface CacheEntry {\n id: string;\n sk: Uint8Array;\n expireAt: number;\n}\n\n/**\n * Key cache manager for managing temporary secret keys\n */\nexport class KeyCache {\n #cachedEntry: CacheEntry | null = null;\n\n #expiryTimer: NodeJS.Timeout | null = null;\n\n #cacheOptions: KeyCacheOptions = {\n enabled: false,\n timeoutMs: 5 * 60 * 1000,\n };\n\n /**\n * KeyCache\n * @param options\n */\n constructor(options?: Partial<KeyCacheOptions>) {\n if (options) {\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n if (Object.keys(options).length > 0 && this.#cachedEntry !== null) {\n this.clearAllCachedKeys();\n }\n\n this.#cacheOptions = { ...this.#cacheOptions, ...options };\n }\n\n getCacheOptions(): KeyCacheOptions {\n return { ...this.#cacheOptions };\n }\n\n isEnabled(): boolean {\n return this.#cacheOptions.enabled;\n }\n\n /**\n * @param credentialId\n * @param sk\n */\n setKey(credentialId: Uint8Array | string, sk: Uint8Array): void {\n if (!this.#cacheOptions.enabled) return;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n const timeout =\n this.#cacheOptions.timeoutMs !== undefined ? this.#cacheOptions.timeoutMs : 5 * 60 * 1000;\n const expireAt = Date.now() + timeout;\n\n this.#clearCachedEntry();\n\n this.#cachedEntry = {\n id,\n sk: new Uint8Array(sk),\n expireAt,\n };\n\n try {\n this.#scheduleExpiry();\n } catch (error) {\n this.#clearCachedEntry();\n throw error;\n }\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n getKey(credentialId: Uint8Array | string): Uint8Array | undefined {\n if (!this.#cacheOptions.enabled) return undefined;\n\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n return this.#getCachedKeyIfValid(id);\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n const id = typeof credentialId === 'string' ? credentialId : bytesToHex(credentialId);\n\n if (this.#cachedEntry && this.#cachedEntry.id === id) {\n this.#clearCachedEntry();\n }\n }\n\n clearAllCachedKeys(): void {\n this.#clearCachedEntry();\n }\n\n /**\n * @param credentialId\n * @returns undefined\n */\n #getCachedKeyIfValid(credentialId: string): Uint8Array | undefined {\n if (!this.#cachedEntry || this.#cachedEntry.id !== credentialId) {\n return undefined;\n }\n\n if (Date.now() < this.#cachedEntry.expireAt) {\n return this.#cachedEntry.sk;\n }\n\n this.#clearCachedEntry();\n return undefined;\n }\n\n #clearCachedEntry(): void {\n if (this.#cachedEntry) {\n this.#clearKey(this.#cachedEntry.sk);\n this.#cachedEntry = null;\n }\n\n if (this.#expiryTimer) {\n clearTimeout(this.#expiryTimer);\n this.#expiryTimer = null;\n }\n }\n\n #scheduleExpiry(): void {\n if (!this.#cachedEntry) return;\n\n const now = Date.now();\n const timeToExpiry = this.#cachedEntry.expireAt - now;\n\n if (timeToExpiry <= 0) {\n this.#clearCachedEntry();\n return;\n }\n\n this.#expiryTimer = setTimeout(() => {\n this.#clearCachedEntry();\n }, timeToExpiry + 1);\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * PRF (Pseudo-Random Function) handler for WebAuthn\n * @packageDocumentation\n */\n\nimport type { GetPrfSecretOptions, PasskeyCreationOptions } from './types.js';\n\nconst PRF_EVAL_INPUT = new TextEncoder().encode('nostr-pwk');\n\n/**\n * @returns PRF\n */\nexport async function isPrfSupported(): Promise<boolean> {\n try {\n const response = await navigator.credentials.get({\n publicKey: {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials: [],\n userVerification: 'required',\n extensions: { prf: { eval: { first: PRF_EVAL_INPUT } } },\n } as PublicKeyCredentialRequestOptions,\n });\n\n if (!response) return false;\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const res = assertion.getClientExtensionResults()?.prf?.results?.first;\n return !!res;\n } catch {\n return false;\n }\n}\n\n/**\n * @param options\n * @returns Credential\n */\nexport async function createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n // Node\n const rpName = options.rp?.name || (typeof location !== 'undefined' ? location.host : 'Nosskey');\n const rpId = options.rp?.id;\n const userName = options.user?.name || 'user@example.com';\n const userDisplayName = options.user?.displayName || 'Nosskey user';\n\n const credentialCreationOptions: CredentialCreationOptions = {\n publicKey: {\n rp: {\n name: rpName,\n id: rpId,\n },\n user: {\n id: crypto.getRandomValues(new Uint8Array(16)),\n name: userName,\n displayName: userDisplayName,\n },\n pubKeyCredParams: options.pubKeyCredParams || [{ type: 'public-key', alg: -7 }], // ES256\n authenticatorSelection: options.authenticatorSelection || {\n residentKey: 'required',\n userVerification: 'required',\n },\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n extensions: options.extensions || { prf: {} }, // PRF拡張を要求\n } as PublicKeyCredentialCreationOptions,\n };\n const cred = (await navigator.credentials.create(\n credentialCreationOptions\n )) as PublicKeyCredential;\n\n return new Uint8Array(cred.rawId);\n}\n\n/**\n * ID\n * @param credentialId \n * @param options PRF(rpId、timeout、userVerification)\n * @returns PRF credentialID\n */\nexport async function getPrfSecret(\n credentialId?: Uint8Array,\n options?: GetPrfSecretOptions\n): Promise<{ secret: Uint8Array; id: Uint8Array }> {\n const allowCredentials = credentialId ? [{ type: 'public-key' as const, id: credentialId }] : [];\n\n const requestOptions: PublicKeyCredentialRequestOptions = {\n challenge: crypto.getRandomValues(new Uint8Array(32)),\n allowCredentials,\n userVerification: options?.userVerification || 'required',\n extensions: {\n prf: { eval: { first: PRF_EVAL_INPUT } },\n } as AuthenticationExtensionsClientInputs,\n };\n\n if (options?.rpId) {\n requestOptions.rpId = options.rpId;\n }\n if (options?.timeout) {\n requestOptions.timeout = options.timeout;\n }\n\n const response = await navigator.credentials.get({\n publicKey: requestOptions,\n });\n\n if (!response) {\n throw new Error('Authentication failed');\n }\n\n const assertion = response as unknown as {\n getClientExtensionResults: () => {\n prf?: {\n results?: {\n first?: ArrayBuffer;\n };\n };\n };\n };\n\n const secret = assertion.getClientExtensionResults()?.prf?.results?.first;\n if (!secret) {\n throw new Error('PRF secret not available');\n }\n\n // response credentialId\n const responseId = new Uint8Array((response as PublicKeyCredential).rawId);\n\n return {\n secret: new Uint8Array(secret),\n id: responseId,\n };\n}\n","import { seckeySigner } from 'rx-nostr-crypto';\nimport { KeyCache } from './key-cache.js';\nimport { createPasskey, getPrfSecret, isPrfSupported } from './prf-handler.js';\nimport type {\n GetPrfSecretOptions,\n KeyCacheOptions,\n KeyOptions,\n NosskeyManagerLike,\n NosskeyManagerOptions,\n NostrEvent,\n NostrKeyInfo,\n NostrKeyStorageOptions,\n PasskeyCreationOptions,\n SignOptions,\n} from './types.js';\n/**\n * Nosskey class for Passkey-Derived Nostr Identity\n * @packageDocumentation\n */\nimport { bytesToHex, hexToBytes } from './utils.js';\n\n// salt(\"nostr-key\" UTF-8)\nconst STANDARD_SALT = '6e6f7374722d6b6579';\n\n/**\n * Nosskey - Passkey-Derived Nostr Keys\n */\nexport class NosskeyManager implements NosskeyManagerLike {\n #keyCache: KeyCache;\n\n // NostrKeyInfo\n #currentKeyInfo: NostrKeyInfo | null = null;\n\n // NostrKeyInfo\n #storageOptions: NostrKeyStorageOptions = {\n enabled: true,\n storageKey: 'nosskey_keyinfo',\n };\n\n // PRF\n #prfOptions: GetPrfSecretOptions = {};\n\n /**\n * NosskeyManager\n * @param options\n */\n constructor(options?: NosskeyManagerOptions) {\n // KeyCache\n this.#keyCache = new KeyCache(options?.cacheOptions);\n\n if (options?.storageOptions) {\n this.#storageOptions = { ...this.#storageOptions, ...options.storageOptions };\n }\n\n // option\n const userVerification = options?.prfOptions?.userVerification ?? 'required';\n if (options?.prfOptions) {\n this.#prfOptions = { ...options.prfOptions, userVerification };\n } else {\n this.#prfOptions = { userVerification };\n }\n\n // NostrKeyInfo\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n }\n }\n }\n\n /**\n * NostrKeyInfo\n * @param options\n */\n setStorageOptions(options: Partial<NostrKeyStorageOptions>): void {\n this.#storageOptions = { ...this.#storageOptions, ...options };\n\n if (options.enabled === false) {\n this.clearStoredKeyInfo();\n }\n }\n\n /**\n * NostrKeyInfo\n */\n getStorageOptions(): NostrKeyStorageOptions {\n return { ...this.#storageOptions };\n }\n\n /**\n * NostrKeyInfo\n * @param keyInfo NostrKeyInfo\n */\n setCurrentKeyInfo(keyInfo: NostrKeyInfo): void {\n this.#currentKeyInfo = keyInfo;\n\n if (this.#storageOptions.enabled) {\n void this.#saveKeyInfoToStorage(keyInfo);\n }\n }\n\n /**\n * NostrKeyInfo\n */\n getCurrentKeyInfo(): NostrKeyInfo | null {\n // NostrKeyInfo\n if (!this.#currentKeyInfo && this.#storageOptions.enabled) {\n this.#currentKeyInfo = this.#loadKeyInfoFromStorage();\n }\n return this.#currentKeyInfo;\n }\n\n /**\n * NostrKeyInfo\n * @returns NostrKeyInfo\n */\n hasKeyInfo(): boolean {\n if (this.#currentKeyInfo) {\n return true;\n }\n\n if (this.#storageOptions.enabled) {\n const loadedKeyInfo = this.#loadKeyInfoFromStorage();\n if (loadedKeyInfo) {\n this.#currentKeyInfo = loadedKeyInfo;\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * NostrKeyInfo\n * @param keyInfo NostrKeyInfo\n */\n async #saveKeyInfoToStorage(keyInfo: NostrKeyInfo): Promise<void> {\n if (!this.#storageOptions.enabled) return;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.setItem(key, JSON.stringify(keyInfo));\n }\n\n /**\n * NostrKeyInfo\n */\n #loadKeyInfoFromStorage(): NostrKeyInfo | null {\n if (!this.#storageOptions.enabled) return null;\n\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return null;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n const data = storage.getItem(key);\n\n if (!data) return null;\n\n try {\n return JSON.parse(data) as NostrKeyInfo;\n } catch (e) {\n console.error('Failed to parse stored NostrKeyInfo', e);\n return null;\n }\n }\n\n /**\n * NostrKeyInfo\n */\n clearStoredKeyInfo(): void {\n const storage =\n this.#storageOptions.storage || (typeof localStorage !== 'undefined' ? localStorage : null);\n\n if (!storage) return;\n\n const key = this.#storageOptions.storageKey || 'nosskey_keyinfo';\n storage.removeItem(key);\n\n // NostrKeyInfo\n this.#currentKeyInfo = null;\n }\n\n /**\n * NIP-07\n * NostrKeyInfo\n */\n async getPublicKey(): Promise<string> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current NostrKeyInfo set');\n }\n return keyInfo.pubkey;\n }\n\n /**\n * NIP-07\n * NostrKeyInfo\n * @param event Nostr\n */\n async signEvent(event: NostrEvent): Promise<NostrEvent> {\n const keyInfo = this.getCurrentKeyInfo();\n if (!keyInfo) {\n throw new Error('No current NostrKeyInfo set');\n }\n return this.signEventWithKeyInfo(event, keyInfo);\n }\n\n /**\n * @param options\n */\n setCacheOptions(options: Partial<KeyCacheOptions>): void {\n this.#keyCache.setCacheOptions(options);\n }\n\n getCacheOptions(): KeyCacheOptions {\n return this.#keyCache.getCacheOptions();\n }\n\n /**\n * @param credentialId\n */\n clearCachedKey(credentialId: Uint8Array | string): void {\n this.#keyCache.clearCachedKey(credentialId);\n }\n\n clearAllCachedKeys(): void {\n this.#keyCache.clearAllCachedKeys();\n }\n\n /**\n * @param options\n * @returns Credential\n */\n async createPasskey(options: PasskeyCreationOptions = {}): Promise<Uint8Array> {\n return createPasskey({\n rp: {\n id: this.#prfOptions.rpId,\n name: this.#prfOptions.rpId,\n },\n authenticatorSelection: {\n userVerification: this.#prfOptions.userVerification,\n },\n ...options,\n });\n }\n\n /**\n * PRF NostrKeyInfo\n * @param credentialId\n * @param options\n */\n async createNostrKey(credentialId?: Uint8Array, options: KeyOptions = {}): Promise<NostrKeyInfo> {\n const { secret: sk, id: responseId } = await getPrfSecret(credentialId, this.#prfOptions);\n\n // secp256k1\n if (sk.every((byte) => byte === 0)) {\n throw new Error('Invalid PRF output: all zeros');\n }\n\n // HEX\n const skHex = bytesToHex(sk);\n\n // rx-nostr-crypto\n const signer = seckeySigner(skHex);\n const publicKey = await signer.getPublicKey();\n\n // NostrKeyInfo\n const keyInfo: NostrKeyInfo = {\n credentialId: bytesToHex(credentialId || responseId),\n pubkey: publicKey,\n salt: STANDARD_SALT, // salt\n ...(options.username && { username: options.username }), // username\n };\n\n return keyInfo;\n }\n\n /**\n * @param event Nostr\n * @param keyInfo NostrKeyInfo\n * @param options\n */\n async signEventWithKeyInfo(\n event: NostrEvent,\n keyInfo: NostrKeyInfo,\n options: SignOptions = {}\n ): Promise<NostrEvent> {\n const { clearMemory = true, tags } = options;\n\n const shouldUseCache = this.#keyCache.isEnabled();\n\n let sk: Uint8Array | undefined;\n\n if (shouldUseCache) {\n sk = this.#keyCache.getKey(keyInfo.credentialId);\n }\n\n if (!sk) {\n const { secret: prfSecret } = await getPrfSecret(\n hexToBytes(keyInfo.credentialId),\n this.#prfOptions\n );\n sk = prfSecret;\n\n if (shouldUseCache) {\n this.#keyCache.setKey(keyInfo.credentialId, sk);\n }\n }\n\n const skHex = bytesToHex(sk);\n\n // rx-nostr-crypto seckeySigner\n const signer = seckeySigner(skHex, { tags });\n const signedEvent = await signer.signEvent(event);\n\n // clearMemory=true\n if (!shouldUseCache && clearMemory) {\n this.#clearKey(sk);\n }\n\n return signedEvent;\n }\n\n /**\n * @param keyInfo NostrKeyInfo\n * @param credentialId NostrKeyInfoのcredentialId\n * @param options\n * @returns \n */\n async exportNostrKey(keyInfo: NostrKeyInfo, credentialId?: Uint8Array): Promise<string> {\n // NostrKeyInfo credentialId\n let usedCredentialId = credentialId;\n\n // credentialId NostrKeyInfo\n if (!usedCredentialId && keyInfo.credentialId) {\n usedCredentialId = hexToBytes(keyInfo.credentialId);\n }\n\n // PRF\n const { secret: sk } = await getPrfSecret(usedCredentialId, this.#prfOptions);\n\n // HEX\n const skHex = bytesToHex(sk);\n\n return skHex;\n }\n\n /**\n * PRF\n */\n async isPrfSupported(): Promise<boolean> {\n return isPrfSupported();\n }\n\n /**\n * @param key\n */\n #clearKey(key: Uint8Array): void {\n key?.fill?.(0);\n }\n}\n","/**\n * Cryptographic utilities for Nosskey\n * @packageDocumentation\n */\n\nconst INFO_BYTES = new TextEncoder().encode('nostr-pwk');\nconst AES_LENGTH = 256; // bits\n\n/**\n * PRF AES-GCM\n * @param secret PRF\n * @param salt\n * @returns AES-GCM\n */\nexport async function deriveAesGcmKey(secret: Uint8Array, salt: Uint8Array): Promise<CryptoKey> {\n const keyMaterial = await crypto.subtle.importKey('raw', secret, 'HKDF', false, ['deriveKey']);\n\n return crypto.subtle.deriveKey(\n { name: 'HKDF', hash: 'SHA-256', salt, info: INFO_BYTES },\n keyMaterial,\n { name: 'AES-GCM', length: AES_LENGTH },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param plaintext\n * @returns\n */\nexport async function aesGcmEncrypt(key: CryptoKey, iv: Uint8Array, plaintext: Uint8Array) {\n const buf = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);\n\n const bytes = new Uint8Array(buf);\n return {\n ciphertext: bytes.slice(0, -16),\n tag: bytes.slice(-16),\n };\n}\n\n/**\n * AES-GCM\n * @param key\n * @param iv\n * @param ct\n * @param tag\n * @returns\n */\nexport async function aesGcmDecrypt(\n key: CryptoKey,\n iv: Uint8Array,\n ct: Uint8Array,\n tag: Uint8Array\n): Promise<Uint8Array> {\n const buf = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv },\n key,\n new Uint8Array([...ct, ...tag])\n );\n return new Uint8Array(buf);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ns-auth-sdk",
3
- "version": "1.2.6",
4
- "description": "SSO library for NS Auth - Authentication, membership, and profile management compatible with applesauce",
3
+ "version": "1.3.0",
4
+ "description": "Decentralized SSO library - Authentication, membership, and profile management",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
@@ -17,8 +17,8 @@
17
17
  "dist"
18
18
  ],
19
19
  "scripts": {
20
- "build": "tsup",
21
- "dev": "tsup --watch",
20
+ "build": "tsdown",
21
+ "dev": "tsdown --watch",
22
22
  "type-check": "tsc --noEmit",
23
23
  "semantic-release": "semantic-release"
24
24
  },
@@ -26,39 +26,40 @@
26
26
  "nostr",
27
27
  "sso",
28
28
  "authentication",
29
- "membership",
30
- "applesauce"
29
+ "membership"
31
30
  ],
32
31
  "author": "",
33
32
  "license": "Apache-2.0",
34
33
  "repository": {
35
34
  "type": "git",
36
- "url": "https://github.com/OneBoardTech/ns-auth-sdk.git"
35
+ "url": "https://github.com/stoic-one/ns-auth-sdk.git"
37
36
  },
38
37
  "publishConfig": {
39
38
  "registry": "https://registry.npmjs.org/",
40
39
  "access": "public"
41
40
  },
42
41
  "peerDependencies": {
42
+ "applesauce-core": "^5.0.0",
43
43
  "react": "^18.0.0",
44
44
  "react-dom": "^18.0.0",
45
- "applesauce-core": "^5.0.0",
46
- "nosskey-sdk": "^0.0.4"
45
+ "rx-nostr": "^3.6.1",
46
+ "rx-nostr-crypto": "^3.1.3"
47
47
  },
48
48
  "dependencies": {
49
- "zustand": "^4.5.5",
49
+ "isomorphic-dompurify": "^2.35.0",
50
50
  "qrcode.react": "^4.2.0",
51
- "react-zxing": "^2.1.0"
51
+ "react-zxing": "^2.1.0",
52
+ "zustand": "^4.5.7"
52
53
  },
53
54
  "devDependencies": {
54
55
  "@semantic-release/changelog": "^6.0.3",
55
56
  "@semantic-release/git": "^10.0.1",
56
57
  "@semantic-release/github": "^9.2.6",
57
- "@semantic-release/npm": "^11.0.2",
58
- "@types/react": "^18.3.5",
59
- "@types/react-dom": "^18.3.0",
60
- "semantic-release": "^23.0.2",
61
- "tsup": "^8.0.0",
62
- "typescript": "^5.6.2"
58
+ "@semantic-release/npm": "^11.0.3",
59
+ "@types/react": "^18.3.27",
60
+ "@types/react-dom": "^18.3.7",
61
+ "semantic-release": "^23.1.1",
62
+ "tsdown": "^0.19.0",
63
+ "typescript": "^5.9.3"
63
64
  }
64
65
  }