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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { ConnectionRepository } from '../repositories/connection.repository';
import { CredentialVaultService } from '../services/credential-vault.service';
import { OAuthCredentialsService } from '../services/oauth-credentials.service';
import { IntegrationSyncLoggerService } from '../services/integration-sync-logger.service';
import { GenericEmployeeSyncService } from '../services/generic-employee-sync.service';
import { DynamicIntegrationRepository } from '../repositories/dynamic-integration.repository';
import { CheckRunRepository } from '../repositories/check-run.repository';
import { db } from '@db';

jest.mock('@db', () => ({
Expand Down Expand Up @@ -99,6 +102,9 @@ describe('SyncController - Google Workspace employees', () => {
provide: IntegrationSyncLoggerService,
useValue: { logSync: jest.fn() },
},
{ provide: GenericEmployeeSyncService, useValue: {} },
{ provide: DynamicIntegrationRepository, useValue: {} },
{ provide: CheckRunRepository, useValue: {} },
],
})
.overrideGuard(HybridAuthGuard)
Expand Down Expand Up @@ -596,9 +602,12 @@ describe('SyncController - Google Workspace employees', () => {
// ── Exclude filter mode ────────────────────────────────────────

describe('exclude filter mode', () => {
it('should NOT deactivate excluded members in exclude mode', async () => {
it('should deactivate existing non-privileged members excluded from sync', async () => {
setupSync({
gwUsers: [makeGwUser('kept@example.com')],
gwUsers: [
makeGwUser('kept@example.com'),
makeGwUser('excluded@example.com'),
],
variables: {
sync_user_filter_mode: 'exclude',
sync_excluded_emails: 'excluded@example.com',
Expand All @@ -613,7 +622,6 @@ describe('SyncController - Google Workspace employees', () => {
makeMember('kept@example.com', { userId: 'user_kept' }),
);

// Excluded member is in the org but not in the GWS active list
(mockedDb.member.findMany as jest.Mock).mockResolvedValue([
makeMember('kept@example.com'),
makeMember('excluded@example.com'),
Expand All @@ -629,7 +637,14 @@ describe('SyncController - Google Workspace employees', () => {
const deactivatedEmails = result.details
.filter((d) => d.status === 'deactivated')
.map((d) => d.email);
expect(deactivatedEmails).not.toContain('excluded@example.com');
expect(deactivatedEmails).toContain('excluded@example.com');
expect(result.details).toContainEqual(
expect.objectContaining({
email: 'excluded@example.com',
status: 'deactivated',
reason: 'User is excluded from Google Workspace sync',
}),
);
});

it('should exclude users from import by email match', async () => {
Expand Down
37 changes: 21 additions & 16 deletions apps/api/src/integration-platform/controllers/sync.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,18 +444,9 @@ export class SyncController {
},
});

const deactivationGwDomains =
effectiveSyncFilterMode === 'include'
? new Set(
ouFilteredUsers.map((u) =>
u.primaryEmail.split('@')[1]?.toLowerCase(),
),
)
: new Set(
filteredUsers.map((u) =>
u.primaryEmail.split('@')[1]?.toLowerCase(),
),
);
const deactivationGwDomains = new Set(
ouFilteredUsers.map((u) => u.primaryEmail.split('@')[1]?.toLowerCase()),
);
const deactivationSuspendedEmails =
effectiveSyncFilterMode === 'include'
? allSuspendedEmails
Expand Down Expand Up @@ -486,12 +477,26 @@ export class SyncController {
continue;
}

// In exclude mode we keep excluded users unchanged and only stop syncing them.
if (
const isExcluded =
effectiveSyncFilterMode === 'exclude' &&
excludedTerms.length > 0 &&
matchesSyncFilterTerms(memberEmail, excludedTerms)
) {
matchesSyncFilterTerms(memberEmail, excludedTerms);

if (isExcluded) {
try {
await db.member.update({
where: { id: member.id },
data: { deactivated: true, isActive: false },
});
results.deactivated++;
results.details.push({
email: member.user.email,
status: 'deactivated',
reason: 'User is excluded from Google Workspace sync',
});
} catch (error) {
this.logger.error(`Error deactivating excluded member: ${error}`);
}
continue;
}

Expand Down
Loading