Skip to content

Commit 7b4cbbe

Browse files
chore(root): Release 2025-05-20 10:13 (#8346)
2 parents e79afbb + ce91078 commit 7b4cbbe

File tree

263 files changed

+4712
-1288
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

263 files changed

+4712
-1288
lines changed

.cspell.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -733,14 +733,17 @@
733733
"oklch",
734734
"Duplicable",
735735
"Radek",
736-
"automators",
736+
"automators",
737737
"VITE",
738738
"snooze",
739739
"unsnooze",
740740
"snoozed",
741741
"unsnoozed",
742742
"automators",
743-
"calcom"
743+
"Svix",
744+
"totp",
745+
"calcom",
746+
"partnerintegration"
744747
],
745748
"flagWords": [],
746749
"patterns": [

.source

apps/api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ See the docs for [Running on Local Machine - API Tests](https://docs.novu.co/com
4343

4444
- Use the `@Get`, `@Post`, `@Put`, `@Delete` decorators to define the HTTP method.
4545
- Use the `@Param`, `@Query`, `@Body` decorators to define the parameters.
46-
- Use the `@UserAuthentication()` decorator to define the guards as well as make it accessible to novu web app.
46+
- Use the `@RequireAuthentication()` decorator to define the guards as well as make it accessible to novu web app.
4747
- Use the @ExternalApiAccessible decorator to define the endpoint as accessible by external API (Users with Api-Key) & The official Novu SDK.
4848

4949
#### Naming conventions

apps/api/migrations/changes-migration.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/* eslint-disable no-console */
22
import '../src/config';
33
import { NestFactory } from '@nestjs/core';
4-
import { AppModule } from '../src/app.module';
54
import {
65
NotificationTemplateRepository,
76
MessageTemplateRepository,
@@ -12,11 +11,12 @@ import {
1211
OrganizationRepository,
1312
} from '@novu/dal';
1413
import { ChangeEntityTypeEnum, MemberRoleEnum } from '@novu/shared';
14+
import { CreateChange, CreateChangeCommand } from '@novu/application-generic';
15+
import { AppModule } from '../src/app.module';
1516
import { CreateEnvironment } from '../src/app/environments-v1/usecases/create-environment/create-environment.usecase';
1617
import { CreateEnvironmentCommand } from '../src/app/environments-v1/usecases/create-environment/create-environment.command';
1718
import { ApplyChange } from '../src/app/change/usecases/apply-change/apply-change.usecase';
1819
import { ApplyChangeCommand } from '../src/app/change/usecases/apply-change/apply-change.command';
19-
import { CreateChange, CreateChangeCommand } from '@novu/application-generic';
2020

2121
export async function run(): Promise<void> {
2222
console.log('Script started');
@@ -43,7 +43,7 @@ export async function run(): Promise<void> {
4343
for (const org of orgs) {
4444
console.log(`Migrating org ${org._id}`);
4545
const member = await memberRepository.findOne({
46-
roles: MemberRoleEnum.ADMIN,
46+
roles: MemberRoleEnum.OSS_ADMIN,
4747
_organizationId: org._id,
4848
});
4949

apps/api/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@novu/api-service",
3-
"version": "2.1.13",
3+
"version": "2.2.0",
44
"description": "description",
55
"author": "",
66
"private": "true",
@@ -102,6 +102,7 @@
102102
"rxjs": "7.8.1",
103103
"sanitize-html": "^2.4.0",
104104
"shortid": "^2.2.16",
105+
"svix": "^1.24.0",
105106
"swagger-ui-express": "^4.4.0",
106107
"uuid": "^8.3.2",
107108
"zod": "^3.23.8",

apps/api/src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { StorageModule } from './app/storage/storage.module';
4343
import { SubscribersModule } from './app/subscribers-v2/subscribers.module';
4444
import { SubscribersV1Module } from './app/subscribers/subscribersV1.module';
4545
import { SupportModule } from './app/support/support.module';
46+
import { WebhooksModule } from './app/webhooks/webhooks.module';
4647
import { TenantModule } from './app/tenant/tenant.module';
4748
import { TestingModule } from './app/testing/testing.module';
4849
import { TopicsV1Module } from './app/topics-v1/topics-v1.module';
@@ -63,6 +64,7 @@ const enterpriseImports = (): Array<Type | DynamicModule | Promise<DynamicModule
6364
modules.push(require('@novu/ee-billing')?.BillingModule.forRoot());
6465
}
6566
modules.push(SupportModule);
67+
modules.push(WebhooksModule);
6668
}
6769

6870
return modules;

apps/api/src/app/analytics/analytics.controller.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
22
import { ApiExcludeController } from '@nestjs/swagger';
33
import { SkipThrottle } from '@nestjs/throttler';
4-
import { AnalyticsService, ExternalApiAccessible, UserSession } from '@novu/application-generic';
4+
import { AnalyticsService, ExternalApiAccessible, UserSession, SkipPermissionsCheck } from '@novu/application-generic';
55
import { UserSessionData } from '@novu/shared';
6-
import { UserAuthentication } from '../shared/framework/swagger/api.key.security';
76
import { HubspotIdentifyFormCommand } from './usecases/hubspot-identify-form/hubspot-identify-form.command';
87
import { HubspotIdentifyFormUsecase } from './usecases/hubspot-identify-form/hubspot-identify-form.usecase';
8+
import { RequireAuthentication } from '../auth/framework/auth.decorator';
99

1010
@Controller({
1111
path: 'telemetry',
1212
})
1313
@SkipThrottle()
14+
@RequireAuthentication()
1415
@ApiExcludeController()
1516
export class AnalyticsController {
1617
constructor(
@@ -20,7 +21,7 @@ export class AnalyticsController {
2021

2122
@Post('/measure')
2223
@ExternalApiAccessible()
23-
@UserAuthentication()
24+
@SkipPermissionsCheck()
2425
async trackEvent(@Body('event') event, @Body('data') data = {}, @UserSession() user: UserSessionData): Promise<any> {
2526
this.analyticsService.track(event, user._id, {
2627
...(data || {}),
@@ -34,8 +35,8 @@ export class AnalyticsController {
3435

3536
@Post('/identify')
3637
@ExternalApiAccessible()
37-
@UserAuthentication()
3838
@HttpCode(HttpStatus.NO_CONTENT)
39+
@SkipPermissionsCheck()
3940
async identifyUser(@Body() body: any, @UserSession() user: UserSessionData) {
4041
if (body.anonymousId) {
4142
this.analyticsService.alias(body.anonymousId, user._id);

apps/api/src/app/auth/auth.controller.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ import { ApiCommonResponses } from '../shared/framework/response.decorator';
3737
import { UpdatePasswordBodyDto } from './dtos/update-password.dto';
3838
import { UpdatePassword } from './usecases/update-password/update-password.usecase';
3939
import { UpdatePasswordCommand } from './usecases/update-password/update-password.command';
40-
import { UserAuthentication } from '../shared/framework/swagger/api.key.security';
4140
import { SwitchOrganizationCommand } from './usecases/switch-organization/switch-organization.command';
4241
import { SwitchOrganization } from './usecases/switch-organization/switch-organization.usecase';
4342
import { AuthService } from './services/auth.service';
43+
import { RequireAuthentication } from './framework/auth.decorator';
4444

4545
@ApiCommonResponses()
4646
@Controller('/auth')
@@ -89,7 +89,7 @@ export class AuthController {
8989
}
9090

9191
@Get('/refresh')
92-
@UserAuthentication()
92+
@RequireAuthentication()
9393
@Header('Cache-Control', 'no-store')
9494
refreshToken(@UserSession() user: UserSessionData) {
9595
if (!user || !user._id) throw new BadRequestException();
@@ -148,7 +148,7 @@ export class AuthController {
148148
}
149149

150150
@Post('/organizations/:organizationId/switch')
151-
@UserAuthentication()
151+
@RequireAuthentication()
152152
@HttpCode(200)
153153
@Header('Cache-Control', 'no-store')
154154
async organizationSwitch(@UserSession() user: UserSessionData, @Param('organizationId') organizationId: string) {
@@ -162,7 +162,7 @@ export class AuthController {
162162

163163
@Post('/update-password')
164164
@Header('Cache-Control', 'no-store')
165-
@UserAuthentication()
165+
@RequireAuthentication()
166166
@HttpCode(HttpStatus.NO_CONTENT)
167167
async updatePassword(@UserSession() user: UserSessionData, @Body() body: UpdatePasswordBodyDto) {
168168
return await this.updatePasswordUsecase.execute(

apps/api/src/app/auth/community.auth.module.config.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { MiddlewareConsumer, ModuleMetadata, Provider, RequestMethod } from '@nestjs/common';
2-
import { JwtModule, JwtService } from '@nestjs/jwt';
2+
import { JwtModule } from '@nestjs/jwt';
33
import { PassportModule } from '@nestjs/passport';
44
import passport from 'passport';
55
import { AuthProviderEnum, PassportStrategyEnum } from '@novu/shared';
@@ -10,15 +10,12 @@ import { UserModule } from '../user/user.module';
1010
import { USE_CASES } from './usecases';
1111
import { SharedModule } from '../shared/shared.module';
1212
import { GitHubStrategy } from './services/passport/github.strategy';
13-
import { OrganizationModule } from '../organization/organization.module';
1413
import { EnvironmentsModuleV1 } from '../environments-v1/environments-v1.module';
1514
import { JwtSubscriberStrategy } from './services/passport/subscriber-jwt.strategy';
1615
import { RootEnvironmentGuard } from './framework/root-environment-guard.service';
1716
import { ApiKeyStrategy } from './services/passport/apikey.strategy';
1817
import { AuthService } from './services/auth.service';
19-
import { RolesGuard } from './framework/roles.guard';
2018
import { CommunityAuthService } from './services/community.auth.service';
21-
import { CommunityUserAuthGuard } from './framework/community.user.auth.guard';
2219

2320
const AUTH_STRATEGIES: Provider[] = [JwtStrategy, ApiKeyStrategy, JwtSubscriberStrategy];
2421

@@ -39,7 +36,7 @@ export function getCommunityAuthModuleConfig(): ModuleMetadata {
3936
}),
4037
];
4138

42-
const baseProviders = [...AUTH_STRATEGIES, AuthService, RolesGuard, RootEnvironmentGuard];
39+
const baseProviders = [...AUTH_STRATEGIES, AuthService, RootEnvironmentGuard];
4340

4441
// Wherever is the string token used, override it with the provider
4542
const injectableProviders = [
@@ -59,22 +56,16 @@ export function getCommunityAuthModuleConfig(): ModuleMetadata {
5956
provide: 'AUTH_SERVICE',
6057
useClass: CommunityAuthService,
6158
},
62-
{
63-
provide: 'USER_AUTH_GUARD',
64-
useClass: CommunityUserAuthGuard,
65-
},
6659
];
6760

6861
return {
69-
imports: [...baseImports, EnvironmentsModuleV1, SharedModule, UserModule, OrganizationModule],
62+
imports: [...baseImports, EnvironmentsModuleV1, SharedModule, UserModule],
7063
controllers: [AuthController],
7164
providers: [...baseProviders, ...injectableProviders, ...USE_CASES],
7265
exports: [
73-
RolesGuard,
7466
RootEnvironmentGuard,
7567
AuthService,
7668
'AUTH_SERVICE',
77-
'USER_AUTH_GUARD',
7869
'USER_REPOSITORY',
7970
'MEMBER_REPOSITORY',
8071
'ORGANIZATION_REPOSITORY',

apps/api/src/app/auth/e2e/clerk.strategy.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Test } from '@nestjs/testing';
33
import { expect } from 'chai';
44
import { EnvironmentRepository } from '@novu/dal';
55
import sinon from 'sinon';
6-
import { ApiAuthSchemeEnum, UserSessionData } from '@novu/shared';
6+
import { ApiAuthSchemeEnum, MemberRoleEnum, UserSessionData, ALL_PERMISSIONS } from '@novu/shared';
77
import { HttpRequestHeaderKeysEnum } from '@novu/application-generic';
88
import { UnauthorizedException } from '@nestjs/common';
99

@@ -35,7 +35,8 @@ describe('ClerkStrategy', () => {
3535
lastName: 'Doe',
3636
profilePicture: 'https://example.com/profile.png',
3737
38-
org_role: 'org:admin',
38+
org_role: MemberRoleEnum.OWNER,
39+
org_permissions: ALL_PERMISSIONS,
3940
externalId: undefined,
4041
externalOrgId: undefined,
4142
};
@@ -73,7 +74,8 @@ describe('ClerkStrategy', () => {
7374
lastName: 'Doe',
7475
7576
organizationId: 'internal-org-123',
76-
roles: ['admin'],
77+
roles: [MemberRoleEnum.OWNER],
78+
permissions: ALL_PERMISSIONS,
7779
environmentId: 'env-123',
7880
scheme: ApiAuthSchemeEnum.BEARER,
7981
});

0 commit comments

Comments
 (0)