Add NIP-46 remote signer auth provider

This commit is contained in:
thePR0M3TH3AN committed 2025-10-21 12:25:41 -04:00
1 parent 73a8d42174
commit 5328168e99
5 files changed
+1234 -3

No files matched your search

+10 -1
View File
@@ -33,7 +33,10 @@ import watchHistoryService from "./watchHistoryService.js";
import r2Service from "./services/r2Service.js";
import PlaybackService from "./services/playbackService.js";
import AuthService from "./services/authService.js";
import { listAuthProviders } from "./services/authProviders/index.js";
import {
listAuthProviders,
initializeAuthProviders,
} from "./services/authProviders/index.js";
import NwcSettingsService from "./services/nwcSettingsService.js";
import nostrService from "./services/nostrService.js";
import DiscussionCountService from "./services/discussionCountService.js";
@@ -350,6 +353,12 @@ class Application {
)
);
initializeAuthProviders({
nostrClient,
authService: this.authService,
logger: (message, ...args) => this.log(message, ...args),
});
this.loginModalController = null;
const loginModalElement = document.getElementById("loginModal") || null;
+13
View File
@@ -5958,6 +5958,19 @@ export class NostrClient {
}
}
}
const nip46Provider = getAuthProvider("nip46");
if (nip46Provider && typeof nip46Provider.clearStorage === "function") {
try {
nip46Provider.clearStorage({ reason: "logout" });
} catch (error) {
if (isDevMode) {
console.warn(
"[nostr] Failed to clear nip46 provider storage during logout:",
error,
);
}
}
}
for (const timer of this.watchHistoryRepublishTimers.values()) {
if (timer && typeof timer.timer === "number") {
clearTimeout(timer.timer);
+47 -1
View File
@@ -1,7 +1,8 @@
import nip07Provider from "./nip07.js";
import nsecProvider from "./nsec.js";
import nip46Provider from "./nip46.js";
const providers = [nip07Provider, nsecProvider].filter(
const providers = [nip07Provider, nsecProvider, nip46Provider].filter(
(provider) => provider && typeof provider.id === "string",
);
@@ -28,5 +29,50 @@ export function listAuthProviders() {
return providers.slice();
}
export function initializeAuthProviders(context = {}) {
for (const provider of providers) {
if (provider && typeof provider.initialize === "function") {
try {
const result = provider.initialize(context);
if (result && typeof result.then === "function") {
result.catch((error) => {
if (context?.logger) {
try {
context.logger(
`[authProviders] Provider "${provider.id}" initialize rejected`,
error,
);
} catch (_) {
// ignore logger failures
}
} else if (typeof console !== "undefined" && console?.warn) {
console.warn(
`[authProviders] Provider "${provider.id}" initialize rejected`,
error,
);
}
});
}
} catch (error) {
if (context?.logger) {
try {
context.logger(
`[authProviders] Provider "${provider.id}" initialize failed`,
error,
);
} catch (_) {
// ignore logger failures
}
} else if (typeof console !== "undefined" && console?.warn) {
console.warn(
`[authProviders] Provider "${provider.id}" initialize failed`,
error,
);
}
}
}
}
}
export { providersById };
export default providers;
File diff suppressed because it is too large. Load diff
+44 -1
View File
@@ -229,6 +229,8 @@ export default class LoginModalController {
: "",
slowTimer: null,
clickHandler: null,
renderResult: null,
uiHooks: null,
};
if (!isDisabled) {
@@ -239,6 +241,34 @@ export default class LoginModalController {
button.addEventListener("click", state.clickHandler);
}
if (typeof ui.render === "function") {
try {
const renderResult = ui.render({
wrapper,
button,
provider,
controller: this,
});
if (renderResult && typeof renderResult === "object") {
state.renderResult = renderResult;
if (renderResult.uiHooks && typeof renderResult.uiHooks === "object") {
state.uiHooks = renderResult.uiHooks;
} else if (
typeof renderResult.setStatus === "function" ||
typeof renderResult.setError === "function" ||
typeof renderResult.setConnectUri === "function"
) {
state.uiHooks = renderResult;
}
}
} catch (error) {
console.error(
`[LoginModalController] Provider "${providerId}" render failed:`,
error,
);
}
}
this.providerStates.set(providerId, state);
return wrapper;
}
@@ -251,6 +281,16 @@ export default class LoginModalController {
state.button.removeEventListener("click", state.clickHandler);
}
this.clearSlowTimer(state);
if (state.renderResult && typeof state.renderResult.destroy === "function") {
try {
state.renderResult.destroy();
} catch (error) {
console.error(
"[LoginModalController] Provider render destroy failed:",
error,
);
}
}
}
invokeCallback(name, ...args) {
@@ -371,7 +411,10 @@ export default class LoginModalController {
this.setLoadingState(providerId, true);
try {
const result = await this.authService.requestLogin({ providerId });
const result = await this.authService.requestLogin({
providerId,
ui: state?.uiHooks || null,
});
this.hide();
this.invokeCallback("onSuccess", result, { provider });
} catch (error) {