Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 84 additions & 18 deletions apps/backend/src/services/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { NotificationService } from '@gitroom/nestjs-libraries/database/prisma/n
import { ForgotReturnPasswordDto } from '@gitroom/nestjs-libraries/dtos/auth/forgot-return.password.dto';
import { EmailService } from '@gitroom/nestjs-libraries/services/email.service';
import { NewsletterService } from '@gitroom/nestjs-libraries/newsletter/newsletter.service';
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';

@Injectable()
export class AuthService {
Expand Down Expand Up @@ -158,30 +159,85 @@ export class AuthService {
bio: user.bio || '',
});
}

if (providerUser.organizations && providerUser.organizations.length > 0) {
const userOrgs = await this._organizationService.getOrgsByUserId(user.id);
const existingOrgIds = new Set(userOrgs.map((o) => o.id));

for (const orgInfo of providerUser.organizations) {
if (!existingOrgIds.has(orgInfo.id)) {
const role = orgInfo.role === 'MEMBER' ? 'USER' : 'ADMIN';
const orgExists = await this._organizationService.getOrgById(orgInfo.id);
if (orgExists) {
await this._organizationService
.addUserToOrg(user.id, makeId(5), orgInfo.id, role)
.catch(() => {});
} else {
await this._organizationService
.createOrgForExistingUser(user.id, orgInfo.name, role === 'ADMIN' ? 'ADMIN' : 'USER', orgInfo.id)
.catch(() => {});
}
}
}
Comment on lines +167 to +181

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The ternary expression role === 'ADMIN' ? 'ADMIN' : 'USER' on line 177 is redundant because role is already defined as either 'USER' or 'ADMIN' on line 169. We can simplify this by passing role directly.

Suggested change
for (const orgInfo of providerUser.organizations) {
if (!existingOrgIds.has(orgInfo.id)) {
const role = orgInfo.role === 'MEMBER' ? 'USER' : 'ADMIN';
const orgExists = await this._organizationService.getOrgById(orgInfo.id);
if (orgExists) {
await this._organizationService
.addUserToOrg(user.id, makeId(5), orgInfo.id, role)
.catch(() => {});
} else {
await this._organizationService
.createOrgForExistingUser(user.id, orgInfo.name, role === 'ADMIN' ? 'ADMIN' : 'USER', orgInfo.id)
.catch(() => {});
}
}
}
for (const orgInfo of providerUser.organizations) {
if (!existingOrgIds.has(orgInfo.id)) {
const role = orgInfo.role === 'MEMBER' ? 'USER' : 'ADMIN';
const orgExists = await this._organizationService.getOrgById(orgInfo.id);
if (orgExists) {
await this._organizationService
.addUserToOrg(user.id, makeId(5), orgInfo.id, role)
.catch(() => {});
} else {
await this._organizationService
.createOrgForExistingUser(user.id, orgInfo.name, role, orgInfo.id)
.catch(() => {});
}
}
}

}

return user;
}

if (!(await this.canRegister(provider))) {
throw new Error('Registration is disabled');
}

const firstOrg = providerUser.organizations && providerUser.organizations[0];
const companyName =
(providerUser.organizations && providerUser.organizations[0]?.name) ||
firstOrg?.name ||
body.company ||
(providerUser.name ? `${providerUser.name}'s Organization` : providerUser.email.split('@')[0]);

const create = await this._organizationService.createOrgAndUser(
{
company: companyName,
email: providerUser.email,
password: '',
provider,
providerId: providerUser.id,
datafast_visitor_id: body.datafast_visitor_id || '',
},
ip,
userAgent
);
let create: any;
if (firstOrg?.id) {
const orgExists = await this._organizationService.getOrgById(firstOrg.id);
if (!orgExists) {
create = await this._organizationService.createOrgAndUser(
{
company: companyName,
email: providerUser.email,
password: '',
provider,
providerId: providerUser.id,
datafast_visitor_id: body.datafast_visitor_id || '',
},
ip,
userAgent
);
} else {
create = await this._organizationService.createOrgAndUser(
{
company: companyName,
email: providerUser.email,
password: '',
provider,
providerId: providerUser.id,
datafast_visitor_id: body.datafast_visitor_id || '',
},
ip,
userAgent
);
}
} else {
create = await this._organizationService.createOrgAndUser(
{
company: companyName,
email: providerUser.email,
password: '',
provider,
providerId: providerUser.id,
datafast_visitor_id: body.datafast_visitor_id || '',
},
ip,
userAgent
);
}
Comment on lines +197 to +240

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The if (firstOrg?.id) block contains three identical branches that call this._organizationService.createOrgAndUser with the exact same arguments. This redundancy makes the code hard to maintain and suggests a logical error, as the first organization's canonical ID is never used during registration.

We can simplify this by removing the redundant conditional branches and making a single call to createOrgAndUser. The actual synchronization of the first organization (including its canonical ID) can then be handled by updating the subsequent loop to start at index 0 instead of 1.

    const create = await this._organizationService.createOrgAndUser(
      {
        company: companyName,
        email: providerUser.email,
        password: '',
        provider,
        providerId: providerUser.id,
        datafast_visitor_id: body.datafast_visitor_id || '',
      },
      ip,
      userAgent
    );


if (providerUser.name) {
await this._userService.changePersonal(create.users[0].user.id, {
Expand All @@ -194,11 +250,21 @@ export class AuthService {
for (let i = 1; i < providerUser.organizations.length; i++) {
const orgInfo = providerUser.organizations[i];
const role = orgInfo.role === 'MEMBER' ? 'USER' : 'ADMIN';
await this._organizationService.createOrgForExistingUser(
create.users[0].user.id,
orgInfo.name,
role
).catch(() => {});
const orgExists = await this._organizationService.getOrgById(orgInfo.id);
if (orgExists) {
await this._organizationService
.addUserToOrg(create.users[0].user.id, makeId(5), orgInfo.id, role)
.catch(() => {});
} else {
await this._organizationService
.createOrgForExistingUser(
create.users[0].user.id,
orgInfo.name,
role === 'ADMIN' ? 'ADMIN' : 'USER',
orgInfo.id
)
.catch(() => {});
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,12 @@ export class OrganizationRepository {
async createOrgForExistingUser(
userId: string,
orgName: string,
role: 'SUPERADMIN' | 'ADMIN' | 'USER' = 'SUPERADMIN'
role: 'SUPERADMIN' | 'ADMIN' | 'USER' = 'SUPERADMIN',
orgId?: string
) {
return this._organization.model.organization.create({
data: {
...(orgId ? { id: orgId } : {}),
name: orgName,
apiKey: AuthService.fixedEncryption(makeId(20)),
allowTrial: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,14 @@ export class OrganizationService {
async createOrgForExistingUser(
userId: string,
orgName: string,
role: 'SUPERADMIN' | 'ADMIN' | 'USER' = 'SUPERADMIN'
role: 'SUPERADMIN' | 'ADMIN' | 'USER' = 'SUPERADMIN',
orgId?: string
) {
return this._organizationRepository.createOrgForExistingUser(
userId,
orgName,
role
role,
orgId
);
}

Expand Down
Loading