Skip to content

Commit 415e2c4

Browse files
committed
Create Identity service as the new authentication facade
In ~/core. Migrate SessionHost consumers to this facade.
1 parent 01e307e commit 415e2c4

22 files changed

+94
-61
lines changed

src/common/session.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CONTROLLER_WATERMARK } from '@nestjs/common/constants.js';
88
import { Context } from '@nestjs/graphql';
99
import { uniq } from 'lodash';
1010
import { type DateTime } from 'luxon';
11-
import { SessionHost } from '../components/authentication/session.host';
11+
import { Identity } from '~/core/authentication';
1212
import { type ScopedRole } from '../components/authorization/dto';
1313
import { UnauthenticatedException } from './exceptions';
1414
import { type ID } from './id-field';
@@ -42,10 +42,10 @@ export function loggedInSession(session: Session): Session {
4242

4343
@Injectable()
4444
export class SessionPipe implements PipeTransform {
45-
constructor(private readonly sessionHost: SessionHost) {}
45+
constructor(private readonly identity: Identity) {}
4646

4747
transform() {
48-
return this.sessionHost.currentMaybe;
48+
return this.identity.currentMaybe;
4949
}
5050
}
5151

src/components/authentication/authentication.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { forwardRef, Global, Module } from '@nestjs/common';
22
import { APP_INTERCEPTOR } from '@nestjs/core';
33
import { SessionPipe } from '~/common/session';
44
import { splitDb } from '~/core';
5+
import { Identity } from '~/core/authentication';
56
import { AuthorizationModule } from '../authorization/authorization.module';
67
import { UserModule } from '../user/user.module';
78
import { AuthenticationGelRepository } from './authentication.gel.repository';
@@ -34,6 +35,7 @@ import { SessionResolver } from './session.resolver';
3435
SessionExtraInfoResolver,
3536
LoginExtraInfoResolver,
3637
RegisterExtraInfoResolver,
38+
Identity,
3739
AuthenticationService,
3840
splitDb(AuthenticationRepository, AuthenticationGelRepository),
3941
{ provide: 'AUTHENTICATION', useExisting: AuthenticationService },
@@ -44,6 +46,7 @@ import { SessionResolver } from './session.resolver';
4446
SessionPipe,
4547
],
4648
exports: [
49+
Identity,
4750
SessionHost,
4851
SessionInterceptor,
4952
AuthenticationService,

src/components/authorization/policy/executor/edge-privileges.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class EdgePrivileges<
5757
: perm.isAllowed({
5858
object: this.object,
5959
resource: this.resource,
60-
session: this.policyExecutor.sessionHost.current,
60+
session: this.policyExecutor.identity.current,
6161
});
6262
}
6363

src/components/authorization/policy/executor/policy-executor.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { forwardRef, Inject, Injectable } from '@nestjs/common';
22
import { CachedByArg } from '@seedcompany/common';
33
import { identity, intersection } from 'lodash';
44
import { type EnhancedResource, type Session } from '~/common';
5+
import { Identity } from '~/core/authentication';
56
import { type QueryFragment } from '~/core/database/query';
6-
import { SessionHost } from '../../../authentication/session.host';
77
import { withoutScope } from '../../dto';
88
import { RoleCondition } from '../../policies/conditions/role.condition';
99
import { type Permission } from '../builder/perm-granter';
@@ -40,7 +40,7 @@ export interface FilterOptions {
4040
@Injectable()
4141
export class PolicyExecutor {
4242
constructor(
43-
readonly sessionHost: SessionHost,
43+
readonly identity: Identity,
4444
private readonly policyFactory: PolicyFactory,
4545
@Inject(forwardRef(() => ConditionOptimizer))
4646
private readonly conditionOptimizer: ConditionOptimizer & {},
@@ -64,7 +64,7 @@ export class PolicyExecutor {
6464
}
6565
}
6666

67-
const session = this.sessionHost.current;
67+
const session = this.identity.current;
6868
const policies = this.getPolicies(session);
6969
const isChildRelation = prop && resource.childKeys.has(prop);
7070

@@ -187,7 +187,7 @@ export class PolicyExecutor {
187187

188188
const other = {
189189
resource: params.resource,
190-
session: this.sessionHost.current,
190+
session: this.identity.current,
191191
};
192192
return query
193193
.comment("Loading policy condition's context")

src/components/authorization/policy/executor/privileges.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
type ResourceShape,
77
type SecuredPropsPlusExtraKey,
88
} from '~/common';
9-
import { SessionHost } from '../../../authentication/session.host';
9+
import { Identity } from '~/core/authentication';
1010
import type { Power } from '../../dto';
1111
import { MissingPowerException } from '../../missing-power.exception';
1212
import {
@@ -23,7 +23,7 @@ import { ResourcePrivileges } from './resource-privileges';
2323
export class Privileges {
2424
constructor(
2525
private readonly policyExecutor: PolicyExecutor,
26-
private readonly sessionHost: SessionHost,
26+
private readonly identity: Identity,
2727
) {}
2828

2929
forResource<TResourceStatic extends ResourceShape<any>>(
@@ -90,7 +90,7 @@ export class Privileges {
9090
* I think this should be replaced in-app code with `.for(X).verifyCan('create')`
9191
*/
9292
verifyPower(power: Power) {
93-
const session = this.sessionHost.current;
93+
const session = this.identity.current;
9494
if (!this.powers.has(power)) {
9595
throw new MissingPowerException(
9696
power,
@@ -102,7 +102,7 @@ export class Privileges {
102102
}
103103

104104
get powers(): Set<Power> {
105-
const session = this.sessionHost.current;
105+
const session = this.identity.current;
106106
const policies = this.policyExecutor.getPolicies(session);
107107
return new Set(policies.flatMap((policy) => [...policy.powers]));
108108
}

src/components/authorization/policy/executor/resource-privileges.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class ResourcePrivileges<TResourceStatic extends ResourceShape<any>> {
106106
: perm.isAllowed({
107107
object: this.object,
108108
resource: this.resource,
109-
session: this.policyExecutor.sessionHost.current,
109+
session: this.policyExecutor.identity.current,
110110
});
111111
}
112112

src/components/comments/comment.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import {
1313
} from '~/common';
1414
import { isAdmin } from '~/common/session';
1515
import { ResourceLoader, ResourcesHost } from '~/core';
16+
import { Identity } from '~/core/authentication';
1617
import { type BaseNode, isBaseNode } from '~/core/database/results';
17-
import { SessionHost } from '../authentication';
1818
import { Privileges } from '../authorization';
1919
import { CommentRepository } from './comment.repository';
2020
import {
@@ -39,7 +39,7 @@ export class CommentService {
3939
private readonly privileges: Privileges,
4040
private readonly resources: ResourceLoader,
4141
private readonly resourcesHost: ResourcesHost,
42-
private readonly sessionHost: SessionHost,
42+
private readonly identity: Identity,
4343
private readonly mentionNotificationService: CommentViaMentionNotificationService,
4444
) {}
4545

@@ -118,7 +118,7 @@ export class CommentService {
118118
}
119119

120120
secureThread(thread: UnsecuredDto<CommentThread>): CommentThread {
121-
const session = this.sessionHost.current;
121+
const session = this.identity.current;
122122
return {
123123
...thread,
124124
firstComment: this.secureComment(thread.firstComment),

src/components/engagement/engagement.rules.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import {
99
UnauthorizedException,
1010
} from '~/common';
1111
import { ILogger, Logger } from '~/core';
12+
import { Identity } from '~/core/authentication';
1213
import { DatabaseService } from '~/core/database';
1314
import { ACTIVE, INACTIVE } from '~/core/database/query';
14-
import { SessionHost } from '../authentication';
1515
import { withoutScope } from '../authorization/dto';
1616
import { ProjectStep } from '../project/dto';
1717
import {
@@ -35,7 +35,7 @@ const rolesThatCanBypassWorkflow: Role[] = [Role.Administrator];
3535
export class EngagementRules {
3636
constructor(
3737
private readonly db: DatabaseService,
38-
private readonly sessionHost: SessionHost,
38+
private readonly identity: Identity,
3939
// eslint-disable-next-line @seedcompany/no-unused-vars
4040
@Logger('engagement:rules') private readonly logger: ILogger,
4141
) {}
@@ -317,7 +317,7 @@ export class EngagementRules {
317317
currentUserRoles?: Role[],
318318
changeset?: ID,
319319
): Promise<EngagementStatusTransition[]> {
320-
const session = this.sessionHost.current;
320+
const session = this.identity.current;
321321
if (session.anonymous) {
322322
return [];
323323
}
@@ -357,7 +357,7 @@ export class EngagementRules {
357357
}
358358

359359
async canBypassWorkflow() {
360-
const session = this.sessionHost.current;
360+
const session = this.identity.current;
361361
const roles = session.roles.map(withoutScope);
362362
return intersection(rolesThatCanBypassWorkflow, roles).length > 0;
363363
}
@@ -369,7 +369,7 @@ export class EngagementRules {
369369
) {
370370
// If current user's roles include a role that can bypass workflow
371371
// stop the check here.
372-
const session = this.sessionHost.current;
372+
const session = this.identity.current;
373373
const currentUserRoles = session.roles.map(withoutScope);
374374
if (intersection(rolesThatCanBypassWorkflow, currentUserRoles).length > 0) {
375375
return;

src/components/progress-report/media/handlers/update-media-metadata-check.handler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { EventsHandler, ResourceLoader } from '~/core';
2-
import { SessionHost } from '../../../authentication';
32
import { Privileges } from '../../../authorization';
43
import { CanUpdateMediaUserMetadataEvent } from '../../../file/media/events/can-update-event';
54
import { ProgressReportMedia as ReportMedia } from '../dto';
@@ -9,7 +8,6 @@ export class ProgressReportUpdateMediaMetadataCheckHandler {
98
constructor(
109
private readonly resources: ResourceLoader,
1110
private readonly privileges: Privileges,
12-
private readonly sessionHost: SessionHost,
1311
) {}
1412

1513
async handle(event: CanUpdateMediaUserMetadataEvent) {

src/components/progress-report/workflow/handlers/progress-report-workflow-notification.handler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import {
99
ILogger,
1010
Logger,
1111
} from '~/core';
12+
import { Identity } from '~/core/authentication';
1213
import {
1314
type ProgressReportStatusChangedProps as EmailReportStatusNotification,
1415
ProgressReportStatusChanged,
1516
} from '~/core/email/templates/progress-report-status-changed.template';
16-
import { AuthenticationService } from '../../../authentication';
1717
import { LanguageService } from '../../../language';
1818
import { PeriodicReportService } from '../../../periodic-report';
1919
import { ProjectService } from '../../../project';
@@ -36,7 +36,7 @@ export class ProgressReportWorkflowNotificationHandler
3636
implements IEventHandler<WorkflowUpdatedEvent>
3737
{
3838
constructor(
39-
private readonly auth: AuthenticationService,
39+
private readonly identity: Identity,
4040
private readonly repo: ProgressReportWorkflowRepository,
4141
private readonly configService: ConfigService,
4242
private readonly userService: UserService,
@@ -113,7 +113,7 @@ export class ProgressReportWorkflowNotificationHandler
113113
languageId: ID,
114114
): Promise<EmailReportStatusNotification> {
115115
const recipientId = receiver.userId ?? this.configService.rootUser.id;
116-
return await this.auth.asUser(recipientId, async () => {
116+
return await this.identity.asUser(recipientId, async () => {
117117
const recipient = receiver.userId
118118
? await this.userService.readOne(recipientId)
119119
: this.fakeUserFromEmailAddress(receiver.email!);

0 commit comments

Comments
 (0)