Skip to content

Commit

Permalink
Merge branch 'next' into patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
scopsy authored Dec 11, 2024
2 parents 2afc80c + 8f69a93 commit e5d8f6d
Show file tree
Hide file tree
Showing 70 changed files with 1,843 additions and 1,381 deletions.
3 changes: 3 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"language": "en",
"words": [
"ABNF",
"ORGANISATION",
"EQAs",
"addrs",
"subscriberpayloaddto",
"adresses",
Expand All @@ -30,6 +32,7 @@
"atext",
"attatchment",
"Attatchment",
"someurl",
"authres",
"authserv",
"autobuild",
Expand Down
2 changes: 1 addition & 1 deletion .idea/runConfigurations/API.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"@novu/application-generic": "workspace:*",
"@novu/dal": "workspace:*",
"@novu/framework": "workspace:*",
"@novu/node": "workspace:*",
"@novu/notifications": "workspace:*",
"@novu/shared": "workspace:*",
"@novu/stateless": "workspace:*",
Expand All @@ -59,7 +58,7 @@
"@sentry/tracing": "^7.40.0",
"@types/newrelic": "^9.14.6",
"@upstash/ratelimit": "^0.4.4",
"@novu/api": "^0.0.1-alpha.56",
"@novu/api": "0.0.1-alpha.85",
"axios": "^1.6.8",
"liquidjs": "^10.14.0",
"bcrypt": "^5.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { v4 as uuidv4 } from 'uuid';
import { differenceInHours, differenceInSeconds, parseISO } from 'date-fns';
import { Novu } from '@novu/node';
import { UserRepository, UserEntity, IUserResetTokenCount } from '@novu/dal';
import { IUserResetTokenCount, UserEntity, UserRepository } from '@novu/dal';
import { buildUserKey, InvalidateCacheService } from '@novu/application-generic';

import { normalizeEmail, PasswordResetFlowEnum } from '@novu/shared';
import { Novu } from '@novu/api';
import { PasswordResetRequestCommand } from './password-reset-request.command';

@Injectable()
Expand Down Expand Up @@ -39,14 +39,17 @@ export class PasswordResetRequest {
await this.userRepository.updatePasswordResetToken(foundUser._id, token, resetTokenCount);

if ((process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'production') && process.env.NOVU_API_KEY) {
const novu = new Novu(process.env.NOVU_API_KEY);
const novu = new Novu({ apiKey: process.env.NOVU_API_KEY });
const resetPasswordLink = PasswordResetRequest.getResetRedirectLink(token, foundUser, command.src);

novu.trigger(process.env.NOVU_TEMPLATEID_PASSWORD_RESET || 'password-reset-llS-wzWMq', {
to: {
subscriberId: foundUser._id,
email: foundUser.email,
},
await novu.trigger({
name: process.env.NOVU_TEMPLATEID_PASSWORD_RESET || 'password-reset-llS-wzWMq',
to: [
{
subscriberId: foundUser._id,
email: foundUser.email,
},
],
payload: {
resetPasswordLink,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class DelayOutputRendererUsecase {
const delayTimeControlType: DelayTimeControlType = DelayTimeControlZodSchema.parse(renderCommand.controlValues);

return {
amount: delayTimeControlType.amount,
amount: delayTimeControlType.amount as number,
type: delayTimeControlType.type,
unit: delayTimeControlType.unit,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class DigestOutputRendererUsecase {
parse.lookBackWindow.unit
) {
return {
amount: parse.amount,
amount: parse.amount as number,
unit: parse.unit,
digestKey: parse.digestKey,
lookBackWindow: {
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/app/events/dtos/trigger-event-request.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class TopicPayloadDto {
@ApiProperty()
topicKey: string;

@ApiProperty({ example: 'Topic', enum: TriggerRecipientsTypeEnum })
@ApiProperty({ example: 'Topic', enum: TriggerRecipientsTypeEnum, enumName: 'TriggerRecipientsTypeEnum' })
type: TriggerRecipientsTypeEnum;
}

Expand Down
85 changes: 31 additions & 54 deletions apps/api/src/app/events/e2e/send-message-push.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import axios from 'axios';
import { expect } from 'chai';
import {
ExecutionDetailsRepository,
Expand All @@ -9,8 +8,8 @@ import {
import { DetailEnum } from '@novu/application-generic';
import { ChannelTypeEnum, PushProviderIdEnum, StepTypeEnum } from '@novu/shared';
import { UserSession } from '@novu/testing';

const axiosInstance = axios.create();
import { Novu } from '@novu/api';
import { initNovuClassSdk } from '../../shared/helpers/e2e/sdk/e2e-sdk.helper';

describe('Trigger event - Send Push Notification - /v1/events/trigger (POST)', () => {
let session: UserSession;
Expand All @@ -19,7 +18,7 @@ describe('Trigger event - Send Push Notification - /v1/events/trigger (POST)', (
const executionDetailsRepository = new ExecutionDetailsRepository();
const integrationRepository = new IntegrationRepository();
const messageRepository = new MessageRepository();

let novuClient: Novu;
before(async () => {
session = new UserSession();
await session.initialize();
Expand All @@ -34,21 +33,19 @@ describe('Trigger event - Send Push Notification - /v1/events/trigger (POST)', (
},
],
});
novuClient = initNovuClassSdk(session);
});

describe('Multiple providers active', () => {
before(async () => {
const payload = {
await novuClient.integrations.create({
providerId: PushProviderIdEnum.EXPO,
channel: ChannelTypeEnum.PUSH,
credentials: { apiKey: '123' },
_environmentId: session.environment._id,
environmentId: session.environment._id,
active: true,
check: false,
};

await session.testAgent.post('/v1/integrations').send(payload);

});
const integrations = await integrationRepository.find({
_environmentId: session.environment._id,
channel: ChannelTypeEnum.PUSH,
Expand All @@ -63,7 +60,7 @@ describe('Trigger event - Send Push Notification - /v1/events/trigger (POST)', (
});

it('should not create any message if subscriber has no configured channel', async () => {
await triggerEvent(session, template);
await triggerEvent(template);

await session.awaitRunningJobs(template._id);

Expand All @@ -88,10 +85,10 @@ describe('Trigger event - Send Push Notification - /v1/events/trigger (POST)', (
});

it('should not create any message if subscriber has configured two providers without device tokens', async () => {
await updateCredentials(session, session.subscriberId, PushProviderIdEnum.FCM, []);
await updateCredentials(session, session.subscriberId, PushProviderIdEnum.EXPO, []);
await updateCredentials(session.subscriberId, PushProviderIdEnum.FCM, []);
await updateCredentials(session.subscriberId, PushProviderIdEnum.EXPO, []);

await triggerEvent(session, template);
await triggerEvent(template);

await session.awaitRunningJobs(template._id);

Expand Down Expand Up @@ -121,10 +118,10 @@ describe('Trigger event - Send Push Notification - /v1/events/trigger (POST)', (
});

it('should not create any message if subscriber has configured one provider without device tokens and the other has invalid device token', async () => {
await updateCredentials(session, session.subscriberId, PushProviderIdEnum.FCM, ['invalidDeviceToken']);
await updateCredentials(session, session.subscriberId, PushProviderIdEnum.EXPO, []);
await updateCredentials(session.subscriberId, PushProviderIdEnum.FCM, ['invalidDeviceToken']);
await updateCredentials(session.subscriberId, PushProviderIdEnum.EXPO, []);

await triggerEvent(session, template);
await triggerEvent(template);

await session.awaitRunningJobs(template._id);

Expand Down Expand Up @@ -160,43 +157,23 @@ describe('Trigger event - Send Push Notification - /v1/events/trigger (POST)', (
expect(genericError).to.be.ok;
});
});
});

async function triggerEvent(session: UserSession, template: NotificationTemplateEntity) {
await axiosInstance.post(
`${session.serverUrl}/v1/events/trigger`,
{
name: template.triggers[0].identifier,
async function triggerEvent(template2) {
await novuClient.trigger({
name: template2.triggers[0].identifier,
to: [{ subscriberId: session.subscriberId }],
payload: {},
},
{
headers: {
authorization: `ApiKey ${session.apiKey}`,
},
}
);
}

async function updateCredentials(
session: UserSession,
subscriberId: string,
providerId: PushProviderIdEnum,
deviceTokens: string[]
) {
await axiosInstance.put(
`${session.serverUrl}/v1/subscribers/${subscriberId}/credentials`,
{
subscriberId,
providerId,
credentials: {
deviceTokens,
},
},
{
headers: {
authorization: `ApiKey ${session.apiKey}`,
});
}
async function updateCredentials(subscriberId: string, providerId: PushProviderIdEnum, deviceTokens: string[]) {
await novuClient.subscribers.credentials.update(
{
providerId,
credentials: {
deviceTokens,
webhookUrl: 'https:www.someurl.com',
},
},
}
);
}
subscriberId
);
}
});
Loading

0 comments on commit e5d8f6d

Please sign in to comment.