-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Information Architecture Feature Branch (#5238)
* feat: [Information Architecture] FF, pre-work, etc * refactor: Use enum in color scheme logic * [Information Architecture] - New Sidebar Nav (#5283) * feat: Tests, visibility button, etc (#5298) * feat: image component (#5331) * feat: image component * feat: pr suggestions * feat: update props * [Information Architecture] API Keys Page (#5305) * feat: Refactor and improve functionality of API Keys page * feat(web): initial user profile page * chore(web): added suggestions from pr #5322 * feat: Reusable IconButton * feat: Extract hook for API Keys * feat: WIP Api changes * test: Test API Keys page * refactor: Clean-up * feat(web): setting user profile page - security section * chore(api,web,dal): added suggestions from the pr #5329 * chore(web): remove unused refetch api keys prop * feat(web,api): user profile page form * chore(web,api,shared): added suggestions from the pr #5381, common interface for update user profile * feat: API Changes for password reset (#5350) * feat(web,api): user profile image upload * chore(web): added suggestion from the pr #5384 * chore(api): branding whitelist web.novu.co domain for tests * [Information Architecture] User Profile | Set Password Flow (#5325) * feat: Setup update form (#5362) * Nv 3449 settings organisation profile page (#5360) * feat: created the organization profile update page * feat: added e2e tests for organization profile update * feat: added v2 settings page without the tabs * chore: updated spec name * fix: tests by updating the endpoint * fix: tests * fix: ci test * chore: Removed useCallback * feat: applied suggestions from the pr * feat: moved storage types to shared package * refactor: separate function for image upload and logourl renaming * feat: add input height constant * feat: use novu logo as org logo * refactor: remove unused imports * fix: test * Update apps/web/src/pages/settings/organization/OrganizationPage.tsx Co-authored-by: Joel Anton <[email protected]> * Update apps/web/src/pages/settings/organization/OrganizationLogo.tsx Co-authored-by: Joel Anton <[email protected]> * Update apps/web/src/pages/settings/organization/OrganizationLogo.tsx Co-authored-by: Joel Anton <[email protected]> * Update apps/web/src/pages/settings/organization/OrganizationLogo.tsx Co-authored-by: Joel Anton <[email protected]> * Update apps/web/src/components/shared/ProfileImage.styles.ts Co-authored-by: Joel Anton <[email protected]> * revert: empty line * Update apps/web/src/pages/settings/organization/OrganizationLogo.tsx Co-authored-by: Joel Anton <[email protected]> * refactor: use type from shared * refactor: updated the props name to use form values --------- Co-authored-by: Paweł <[email protected]> Co-authored-by: Joel Anton <[email protected]> * [Information Architecture] Follow-ups & Clean-up (#5408) * [Information Architecture] Webhook Page (#5395) * Nv 3455 settings branding page (#5407) * feat: created the organization profile update page * feat: added v2 settings page without the tabs * feat: applied suggestions from the pr * feat: moved storage types to shared package * feat: use novu logo as org logo * refactor: remove unused imports * feat: add additional fields to branding api * feat: branding form v2 * feat: added v2 branding form to route * fix: spacing between title and input * fix: remove onerror * chore: add deprecation * fix: typo * revert: empty line * refactor: divided brand form into sub components and applied pr suggestions * chore: remove unused import * feat: update types * feat: use type * refactor: updated prop types name * fix: spell check * fix: wrong css prop * fix: add theme based colors * refactor: format * feat: applied pr suggestions * fix: typo * fix: navigation width when information architecture is disabled (#5424) * fix: Tweak spacing * fix: NV-3667 | Hide tooltip when no content * fix: NV-3668 | Hide changes in prod env * fix: NV-3666 | Branding page button * fix: NV-3679 | Re-order inputs * fix: NV-3665 | Update margin values * fix: Remove forced feature flag * fix: Update logo asset * fix: NV-3664 | Change Profile inputs per Nik * fix: Styling tweaks * fix: Use DS value * test: Add test util for debugging responses * fix: Remove host restriction in test * test: Add debugging helpers to e2e * test: Fix main nav spec * test: Fix user profile spec * test: Fix clipboard flakiness -- yay! * fix: Use panda values -- really to re-run CI though * fix: CI web tests * fix: tests * fix: allow http only in local env * fix: enable submit btn * fix: skip un-implemented feature tests * fix: updated password to meet validation requirements * fix: close color picker * fix: data test id and password * fix: get sub value and intercept * fix: editor not submiting * fix: add side nav * revert: changes * test: Force when off screen * test: More force * test: Attempt flakiness fix for org switcher * refactor: Extract SidebarFormless and reuse const + styles * refactor: Use new SidebarFormless component * ci: Skip playwright test * ci: Clean-up to retrigger pipelines * test: Add mock feature flag false to old test --------- Co-authored-by: Joel Anton <[email protected]> * test: Attempt wait * fix: organization switch test * test: Move visit to test instead of beforeEach --------- Co-authored-by: Joel Anton <[email protected]> Co-authored-by: Paweł <[email protected]> Co-authored-by: Paweł Tymczuk <[email protected]>
- Loading branch information
1 parent
26f5bfb
commit c17dde5
Showing
211 changed files
with
6,492 additions
and
431 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { passwordConstraints } from '@novu/shared'; | ||
import { IsNotEmpty, Matches, MaxLength, MinLength } from 'class-validator'; | ||
|
||
export class UpdatePasswordBodyDto { | ||
@IsNotEmpty() | ||
@MinLength(passwordConstraints.minLength) | ||
@MaxLength(passwordConstraints.maxLength) | ||
@Matches(passwordConstraints.pattern, { | ||
message: | ||
'The new password must contain minimum 8 and maximum 64 characters,' + | ||
' at least one uppercase letter, one lowercase letter, one number and one special character #?!@$%^&*()-', | ||
}) | ||
newPassword: string; | ||
|
||
@IsNotEmpty() | ||
confirmPassword: string; | ||
|
||
@IsNotEmpty() | ||
currentPassword: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import { IJwtPayload } from '@novu/shared'; | ||
import { CYPRESS_USER_PASSWORD, UserSession } from '@novu/testing'; | ||
import { expect } from 'chai'; | ||
import * as jwt from 'jsonwebtoken'; | ||
|
||
const NEW_PASSWORD = 'newPassword123@'; | ||
const PASSWORD_ERROR_MESSAGE = | ||
'The new password must contain minimum 8 and maximum 64 characters,' + | ||
' at least one uppercase letter, one lowercase letter, one number and one special character #?!@$%^&*()-'; | ||
|
||
describe('User update password - /auth/update-password (POST)', async () => { | ||
let session: UserSession; | ||
|
||
before(async () => { | ||
session = new UserSession(); | ||
await session.initialize(); | ||
}); | ||
|
||
it('should update password', async () => { | ||
const { statusCode } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: NEW_PASSWORD, | ||
confirmPassword: NEW_PASSWORD, | ||
}); | ||
|
||
expect(statusCode).to.equal(204); | ||
|
||
const { body: loginBody } = await session.testAgent.post('/v1/auth/login').send({ | ||
email: session.user.email, | ||
password: NEW_PASSWORD, | ||
}); | ||
|
||
const jwtContent = (await jwt.decode(loginBody.data.token)) as IJwtPayload; | ||
|
||
expect(jwtContent.firstName).to.equal(session.user.firstName); | ||
expect(jwtContent.lastName).to.equal(session.user.lastName); | ||
expect(jwtContent.email).to.equal(session.user.email); | ||
}); | ||
|
||
it('should fail on bad current password', async () => { | ||
const { body } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: '123123213', | ||
newPassword: NEW_PASSWORD, | ||
confirmPassword: NEW_PASSWORD, | ||
}); | ||
|
||
expect(body.statusCode).to.equal(401); | ||
expect(body.message).to.contain('Unauthorized'); | ||
}); | ||
|
||
it('should fail on mismatched passwords', async () => { | ||
const { body } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: NEW_PASSWORD, | ||
confirmPassword: '123123213', | ||
}); | ||
|
||
expect(body.statusCode).to.equal(400); | ||
expect(body.message).to.contain('Passwords do not match'); | ||
}); | ||
|
||
it('should fail on bad password', async () => { | ||
const { body: validLengthBody } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: '12345678', | ||
confirmPassword: '12345678', | ||
}); | ||
|
||
expect(validLengthBody.statusCode).to.equal(400); | ||
expect(validLengthBody.message[0]).to.equal(PASSWORD_ERROR_MESSAGE); | ||
}); | ||
|
||
it('should fail on password missing upper case letter', async () => { | ||
const { body } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: 'abcde@12345', | ||
confirmPassword: 'abcde@12345', | ||
}); | ||
|
||
expect(body.statusCode).to.equal(400); | ||
expect(body.message[0]).to.equal(PASSWORD_ERROR_MESSAGE); | ||
}); | ||
|
||
it('should fail on password missing lower case letter', async () => { | ||
const { body } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: 'ABCDE@12345', | ||
confirmPassword: 'ABCDE@12345', | ||
}); | ||
|
||
expect(body.statusCode).to.equal(400); | ||
expect(body.message[0]).to.equal(PASSWORD_ERROR_MESSAGE); | ||
}); | ||
|
||
it('should fail on password missing special characters', async () => { | ||
const { body } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: 'ABCabc12345', | ||
confirmPassword: 'ABCabc12345', | ||
}); | ||
|
||
expect(body.statusCode).to.equal(400); | ||
expect(body.message[0]).to.equal(PASSWORD_ERROR_MESSAGE); | ||
}); | ||
|
||
it('should fail on password missing numbers', async () => { | ||
const { body } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: 'ABCabc@ABCDE', | ||
confirmPassword: 'ABCabc@ABCDE', | ||
}); | ||
|
||
expect(body.statusCode).to.equal(400); | ||
expect(body.message[0]).to.equal(PASSWORD_ERROR_MESSAGE); | ||
}); | ||
|
||
it('should fail if password length is less than 8 or more then 64', async () => { | ||
const { body: minimumLengthBody } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: '123', | ||
confirmPassword: '123', | ||
}); | ||
|
||
expect(minimumLengthBody.statusCode).to.equal(400); | ||
expect(minimumLengthBody.message[0]).to.equal(PASSWORD_ERROR_MESSAGE); | ||
|
||
const { body: maxLengthBody } = await session.testAgent.post('/v1/auth/update-password').send({ | ||
currentPassword: CYPRESS_USER_PASSWORD, | ||
newPassword: 'Ab1@'.repeat(20), | ||
confirmPassword: 'Ab1@'.repeat(20), | ||
}); | ||
|
||
expect(maxLengthBody.statusCode).to.equal(400); | ||
expect(maxLengthBody.message[0]).to.equal(PASSWORD_ERROR_MESSAGE); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 6 additions & 1 deletion
7
apps/api/src/app/auth/usecases/password-reset-request/password-reset-request.command.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,13 @@ | ||
import { IsDefined, IsEmail } from 'class-validator'; | ||
import { IsDefined, IsEmail, IsEnum, IsOptional } from 'class-validator'; | ||
import { PasswordResetFlowEnum } from '@novu/shared'; | ||
import { BaseCommand } from '../../../shared/commands/base.command'; | ||
|
||
export class PasswordResetRequestCommand extends BaseCommand { | ||
@IsEmail() | ||
@IsDefined() | ||
email: string; | ||
|
||
@IsEnum(PasswordResetFlowEnum) | ||
@IsOptional() | ||
src?: PasswordResetFlowEnum; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
apps/api/src/app/auth/usecases/update-password/update-password.command.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { passwordConstraints } from '@novu/shared'; | ||
import { IsNotEmpty, Matches, MaxLength, MinLength } from 'class-validator'; | ||
import { EnvironmentWithUserCommand } from '../../../shared/commands/project.command'; | ||
|
||
export class UpdatePasswordCommand extends EnvironmentWithUserCommand { | ||
@IsNotEmpty() | ||
@MinLength(passwordConstraints.minLength) | ||
@MaxLength(passwordConstraints.maxLength) | ||
@Matches(passwordConstraints.pattern, { | ||
message: | ||
'The new password must contain minimum 8 and maximum 64 characters,' + | ||
' at least one uppercase letter, one lowercase letter, one number and one special character #?!@$%^&*()-', | ||
}) | ||
newPassword: string; | ||
|
||
@IsNotEmpty() | ||
confirmPassword: string; | ||
|
||
@IsNotEmpty() | ||
currentPassword: string; | ||
} |
Oops, something went wrong.