Fix profile broadcasting during signup (issue #201)

- Publish kind 0 profile event immediately on signup instead of empty array
- Use user relays if available, fallback to DEFAULT_RELAYS during onboarding
- Keep existing 'protected by default' behavior with PROTECTED tag
- Remove PROFILE from space join rebroadcast to avoid duplicates
- Await user data broadcasts in space join flows for reliability
- Add clear inline comments explaining changes
This commit is contained in:
2026-04-16 21:13:56 +05:30
parent 1c8457a4bf
commit 9f3d21cc4c
4 changed files with 20 additions and 15 deletions
+10 -10
View File
@@ -37,21 +37,21 @@
const login = () => pushModal(LogIn) const login = () => pushModal(LogIn)
const completeSignup = () => { const completeSignup = async () => {
// Add default outbox/inbox relays // Add default outbox/inbox relays
publishThunk({ await publishThunk({
event: makeEvent(RELAYS, {tags: DEFAULT_RELAYS.map(url => ["r", url])}), event: makeEvent(RELAYS, {tags: DEFAULT_RELAYS.map(url => ["r", url])}),
relays: [...INDEXER_RELAYS, ...DEFAULT_RELAYS], relays: [...INDEXER_RELAYS, ...DEFAULT_RELAYS],
}) }).complete
// Add default messaging relays // Add default messaging relays
publishThunk({ await publishThunk({
event: makeEvent(MESSAGING_RELAYS, {tags: DEFAULT_MESSAGING_RELAYS.map(url => ["r", url])}), event: makeEvent(MESSAGING_RELAYS, {tags: DEFAULT_MESSAGING_RELAYS.map(url => ["r", url])}),
relays: DEFAULT_RELAYS, relays: DEFAULT_RELAYS,
}) }).complete
// Save the user's profile // Save the user's profile
initProfile(getKey<Profile>("signup.profile")!) await initProfile(getKey<Profile>("signup.profile")!).complete
// Don't show any notifications for old content // Don't show any notifications for old content
setChecked("*") setChecked("*")
@@ -65,23 +65,23 @@
start: () => pushModal(SignUpEmail, {next: flows.email.profile}), start: () => pushModal(SignUpEmail, {next: flows.email.profile}),
profile: () => pushModal(SignUpProfile, {next: flows.email.complete}), profile: () => pushModal(SignUpProfile, {next: flows.email.complete}),
complete: () => pushModal(SignUpComplete, {next: flows.email.finalize}), complete: () => pushModal(SignUpComplete, {next: flows.email.finalize}),
finalize: () => { finalize: async () => {
const email = getKey<string>("signup.email")! const email = getKey<string>("signup.email")!
const clientOptions = getKey<ClientOptions>("signup.clientOptions")! const clientOptions = getKey<ClientOptions>("signup.clientOptions")!
loginWithPomade(clientOptions, email) loginWithPomade(clientOptions, email)
completeSignup() await completeSignup()
}, },
}, },
nostr: { nostr: {
start: () => pushModal(SignUpProfile, {next: flows.nostr.key}), start: () => pushModal(SignUpProfile, {next: flows.nostr.key}),
key: () => pushModal(SignUpKey, {next: flows.nostr.complete}), key: () => pushModal(SignUpKey, {next: flows.nostr.complete}),
complete: () => pushModal(SignUpComplete, {next: flows.nostr.finalize}), complete: () => pushModal(SignUpComplete, {next: flows.nostr.finalize}),
finalize: () => { finalize: async () => {
const secret = getKey<string>("signup.secret")! const secret = getKey<string>("signup.secret")!
loginWithNip01(secret) loginWithNip01(secret)
completeSignup() await completeSignup()
}, },
}, },
} }
+1 -1
View File
@@ -71,7 +71,7 @@
await addSpaceMembership(url) await addSpaceMembership(url)
await goto(makeSpacePath(url), {replaceState: true}) await goto(makeSpacePath(url), {replaceState: true})
broadcastUserData([url]) await broadcastUserData([url])
relaysMostlyRestricted.update(dissoc(url)) relaysMostlyRestricted.update(dissoc(url))
pushToast({message: "Welcome to the space!"}) pushToast({message: "Welcome to the space!"})
} }
+1 -1
View File
@@ -59,7 +59,7 @@
await addSpaceMembership(url) await addSpaceMembership(url)
await goto(makeSpacePath(url), {replaceState: true}) await goto(makeSpacePath(url), {replaceState: true})
broadcastUserData([url]) await broadcastUserData([url])
relaysMostlyRestricted.update(dissoc(url)) relaysMostlyRestricted.update(dissoc(url))
pushToast({message: "Welcome to the space!"}) pushToast({message: "Welcome to the space!"})
} catch (e) { } catch (e) {
+8 -3
View File
@@ -83,6 +83,7 @@ import {
SETTINGS, SETTINGS,
PROTECTED, PROTECTED,
INDEXER_RELAYS, INDEXER_RELAYS,
DEFAULT_RELAYS,
DEFAULT_BLOSSOM_SERVERS, DEFAULT_BLOSSOM_SERVERS,
userSpaceUrls, userSpaceUrls,
userSettingsValues, userSettingsValues,
@@ -125,7 +126,8 @@ export const prependParent = (
export const broadcastUserData = async (relays: string[]) => { export const broadcastUserData = async (relays: string[]) => {
const authors = [pubkey.get()!] const authors = [pubkey.get()!]
const kinds = [RELAYS, MESSAGING_RELAYS, FOLLOWS, PROFILE] // Profile is published during onboarding, so space joins should not rebroadcast it.
const kinds = [RELAYS, MESSAGING_RELAYS, FOLLOWS]
const events = repository.query([{kinds, authors}]) const events = repository.query([{kinds, authors}])
for (const event of events) { for (const event of events) {
@@ -678,6 +680,10 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) =>
// Update Profile // Update Profile
export const initProfile = (profile: Profile) => { export const initProfile = (profile: Profile) => {
const router = Router.get()
const userRelays = router.FromUser().getUrls()
const relays = userRelays.length ? userRelays : DEFAULT_RELAYS
const template = createProfile(profile) const template = createProfile(profile)
// Start out protected by default // Start out protected by default
@@ -685,8 +691,7 @@ export const initProfile = (profile: Profile) => {
const event = makeEvent(PROFILE, template) const event = makeEvent(PROFILE, template)
// Don't publish anywhere yet, wait until they join a space return publishThunk({event, relays})
return publishThunk({event, relays: []})
} }
export const updateProfile = ({ export const updateProfile = ({