@@ -51,7 +51,7 @@ const asPostgrestFailure = <T>(
5151const spaceValidator = ( space : SpaceCreationInput ) : string | null => {
5252 if ( ! space || typeof space !== "object" )
5353 return "Invalid request body: expected a JSON object." ;
54- const { name, url, platform, password } = space ;
54+ const { name, url, platform, password, accountLocalId , accountName } = space ;
5555
5656 if ( ! name || typeof name !== "string" || name . trim ( ) === "" )
5757 return "Missing or invalid name." ;
@@ -61,6 +61,12 @@ const spaceValidator = (space: SpaceCreationInput): string | null => {
6161 return "Missing or invalid platform." ;
6262 if ( ! password || typeof password !== "string" || password . length < 8 )
6363 return "password must be at least 8 characters" ;
64+ if ( platform === "Obsidian" ) {
65+ if ( ! accountLocalId || typeof accountLocalId !== "string" )
66+ return "Missing or invalid accountLocalId for Obsidian platform." ;
67+ if ( ! accountName || typeof accountName !== "string" )
68+ return "Missing or invalid accountName for Obsidian platform." ;
69+ }
6470 return null ;
6571} ;
6672
@@ -95,62 +101,90 @@ const processAndGetOrCreateSpace = async (
95101 const space_id = result . data . id ;
96102
97103 // this is related but each step is idempotent, so con retry w/o transaction
98- const email = spaceAnonUserEmail ( platform , result . data . id ) ;
99- let anonymousUser : User | null = null ;
104+ // For Obsidian: create real user account (not anonymous)
105+ // For Roam: create anonymous account
106+ let email : string ;
107+ let accountLocalIdForStorage : string ;
108+ let accountName : string ;
109+ let agentType : "person" | "anonymous" ;
110+
111+ if ( platform === "Obsidian" ) {
112+ if ( ! data . accountLocalId || ! data . accountName ) {
113+ return asPostgrestFailure < SpaceRecord > (
114+ "accountLocalId and accountName are required for Obsidian platform" ,
115+ "invalid space" ,
116+ ) ;
117+ }
118+ email = data . accountLocalId ;
119+ accountLocalIdForStorage = data . accountLocalId ;
120+ accountName = data . accountName ;
121+ agentType = "person" ;
122+ } else {
123+ email = spaceAnonUserEmail ( platform , result . data . id ) ;
124+ accountLocalIdForStorage = email ;
125+ accountName = `Anonymous of space ${ space_id } ` ;
126+ agentType = "anonymous" ;
127+ }
128+
129+ let authUser : User | null = null ;
100130 {
101- const { error, data } = await supabase . auth . signInWithPassword ( {
102- email,
103- password,
104- } ) ;
131+ const { error : signInError , data : signInData } =
132+ await supabase . auth . signInWithPassword ( {
133+ email,
134+ password,
135+ } ) ;
105136
106137 if (
107- error &&
138+ signInError &&
108139 ! (
109- error . code === "invalid_credentials" ||
110- error . message === "Invalid login credentials"
140+ signInError . code === "invalid_credentials" ||
141+ signInError . message === "Invalid login credentials"
111142 )
112143 ) {
113144 // Handle unexpected errors
114- return asPostgrestFailure ( error . message , "authentication_error" ) ;
145+ return asPostgrestFailure ( signInError . message , "authentication_error" ) ;
115146 }
116- anonymousUser = data . user ;
147+ authUser = signInData ? .user ?? null ;
117148 await supabase . auth . signOut ( { scope : "local" } ) ;
118149 }
119- if ( anonymousUser === null ) {
120- const resultCreateAnonymousUser = await supabase . auth . admin . createUser ( {
150+
151+ if ( authUser === null ) {
152+ const resultCreateUser = await supabase . auth . admin . createUser ( {
121153 email,
122154 password,
123155 email_confirm : true ,
124156 } ) ;
125- if ( resultCreateAnonymousUser . error ) {
157+ if ( resultCreateUser . error ) {
126158 return {
127159 count : null ,
128- status : resultCreateAnonymousUser . error . status || - 1 ,
129- statusText : resultCreateAnonymousUser . error . message ,
160+ status : resultCreateUser . error . status || - 1 ,
161+ statusText : resultCreateUser . error . message ,
130162 data : null ,
131163 error : new PostgrestError ( {
132- message : resultCreateAnonymousUser . error . message ,
164+ message : resultCreateUser . error . message ,
133165 details :
134- typeof resultCreateAnonymousUser . error . cause === "string"
135- ? resultCreateAnonymousUser . error . cause
166+ typeof resultCreateUser . error . cause === "string"
167+ ? resultCreateUser . error . cause
136168 : "" ,
137169 hint : "" ,
138- code : resultCreateAnonymousUser . error . code || "unknown" ,
170+ code : resultCreateUser . error . code || "unknown" ,
139171 } ) ,
140- } ; // space created but not its user, try again
172+ } ;
141173 }
142- anonymousUser = resultCreateAnonymousUser . data . user as User ;
174+ authUser = resultCreateUser . data . user as User ;
143175 }
144- // NOTE: The next few steps could be done as the new user, except the SpaceAccess
145- const anonPlatformUserResult = await supabase
176+
177+ // For Obsidian: real user with name=vaultName, agent_type=person
178+ // For Roam: anonymous account
179+ const platformAccountResult = await supabase
146180 . from ( "PlatformAccount" )
147181 . upsert (
148182 {
149183 platform,
150- account_local_id : email ,
151- name : `Anonymous of space ${ space_id } ` ,
152- agent_type : "anonymous" ,
153- dg_account : anonymousUser . id ,
184+ account_local_id : accountLocalIdForStorage ,
185+ name : accountName ,
186+ agent_type : agentType ,
187+ dg_account : authUser . id ,
154188 } ,
155189 {
156190 onConflict : "account_local_id,platform" ,
@@ -160,14 +194,14 @@ const processAndGetOrCreateSpace = async (
160194 )
161195 . select ( )
162196 . single ( ) ;
163- if ( anonPlatformUserResult . error ) return anonPlatformUserResult ;
197+ if ( platformAccountResult . error ) return platformAccountResult ;
164198
165- const resultAnonUserSpaceAccess = await supabase
199+ const resultUserSpaceAccess = await supabase
166200 . from ( "SpaceAccess" )
167201 . upsert (
168202 {
169203 space_id,
170- account_id : anonPlatformUserResult . data . id ,
204+ account_id : platformAccountResult . data . id ,
171205 editor : true ,
172206 } ,
173207 {
@@ -178,7 +212,7 @@ const processAndGetOrCreateSpace = async (
178212 )
179213 . select ( )
180214 . single ( ) ;
181- if ( resultAnonUserSpaceAccess . error ) return resultAnonUserSpaceAccess ; // space created but not connected, try again
215+ if ( resultUserSpaceAccess . error ) return resultUserSpaceAccess ; // space created but not connected, try again
182216 return result ;
183217} ;
184218
0 commit comments