@@ -269,6 +269,19 @@ export class OrganizationService {
269269 }
270270
271271 public async joinOrganization ( userId : string , inviteId : string ) : Promise < string > {
272+ const user = await this . userDB . findUserById ( userId ) ;
273+ if ( ! user ) {
274+ throw new ApplicationError ( ErrorCodes . INTERNAL_SERVER_ERROR , `User ${ userId } not found` ) ;
275+ }
276+
277+ const mayJoinOrganization = await this . userAuthentication . mayJoinOrganization ( user ) ;
278+ if ( ! mayJoinOrganization ) {
279+ throw new ApplicationError (
280+ ErrorCodes . PERMISSION_DENIED ,
281+ "Organizational accounts are not allowed to join other organizations" ,
282+ ) ;
283+ }
284+
272285 // Invites can be used by anyone, as long as they know the invite ID, hence needs no resource guard
273286 const invite = await this . teamDB . findTeamMembershipInviteById ( inviteId ) ;
274287 if ( ! invite || invite . invalidationTime !== "" ) {
@@ -277,10 +290,6 @@ export class OrganizationService {
277290 if ( await this . teamDB . hasActiveSSO ( invite . teamId ) ) {
278291 throw new ApplicationError ( ErrorCodes . NOT_FOUND , "Invites are disabled for SSO-enabled organizations." ) ;
279292 }
280- const user = await this . userDB . findUserById ( userId ) ;
281- if ( ! user ) {
282- throw new ApplicationError ( ErrorCodes . INTERNAL_SERVER_ERROR , `User ${ userId } not found` ) ;
283- }
284293
285294 // set skipRoleUpdate=true to avoid member/owner click join link again cause role change
286295 await runWithSubjectId ( SYSTEM_USER , ( ) =>
0 commit comments