Skip to content
Open
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
13 changes: 13 additions & 0 deletions api/src/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,19 @@ export class UserController {
return await this.userService.isUserConfirmationTokenValid(dto);
}

@Post('is-reset-token-valid')
@ApiOperation({
summary: 'Verifies token is valid',
operationId: 'isUserResetTokenValid',
})
@ApiOkResponse({ type: SuccessDTO })
@UseGuards(OptionalAuthGuard, PermissionGuard)
async isUserResetTokenValid(
@Body() dto: ConfirmationRequest,
): Promise<SuccessDTO> {
return await this.userService.isUserResetTokenValid(dto);
}

@Post('advocate-from-token')
@ApiOperation({
summary: 'Get advocate user from confirmation token',
Expand Down
15 changes: 10 additions & 5 deletions api/src/services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
BadRequestException,
Injectable,
NotFoundException,
UnauthorizedException,
} from '@nestjs/common';
import { CookieOptions, Response } from 'express';
Expand Down Expand Up @@ -328,17 +327,23 @@ export class AuthService {
});

if (!user) {
throw new NotFoundException(
console.error(
`user resetToken: ${dto.token} was requested but not found`,
);
throw new UnauthorizedException('tokenMissing');
}

const token: IdDTO = verify(dto.token, process.env.APP_SECRET) as IdDTO;

let token: IdDTO = { id: undefined };
try {
token = verify(dto.token, process.env.APP_SECRET) as IdDTO;
} catch (e) {
throw new UnauthorizedException('tokenExpired');
}
if (token.id !== user.id) {
throw new UnauthorizedException(
console.error(
`resetToken ${dto.token} does not match user ${user.id}'s reset token (${user.resetToken})`,
);
throw new UnauthorizedException('tokenExpired');
}
await this.snapshotCreateService.createUserSnapshot(user.id);
await this.prisma.userAccounts.update({
Expand Down
46 changes: 46 additions & 0 deletions api/src/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,52 @@ export class UserService {
}
}

/*
checks to see if the reset token is valid
*/
async isUserResetTokenValid(dto: ConfirmationRequest): Promise<SuccessDTO> {
try {
const token = verify(dto.token, process.env.APP_SECRET) as IdDTO;

const storedUser = await this.prisma.userAccounts.findUnique({
where: {
id: token.id,
},
});
this.checkUserAndToken(storedUser.id, dto.token, storedUser.resetToken);

return {
success: true,
} as SuccessDTO;
} catch (_) {
try {
const storedUser = await this.prisma.userAccounts.findFirst({
where: {
resetToken: dto.token,
},
});
this.checkUserAndToken(storedUser.id, dto.token, storedUser.resetToken);
} catch (e) {
console.error('isUserResetTokenValid error = ', e);
}
}
}

checkUserAndToken(
userId: string,
incomingToken: string,
storedToken: string,
): void {
if (!userId) {
throw new NotFoundException(
`user reset token ${incomingToken} was requested but not found`,
);
}
if (!incomingToken || !storedToken || incomingToken !== storedToken) {
throw new BadRequestException('tokenMissing');
}
}

/*
Returns an advocate user's basic info by validating their confirmation token.
Used to pre-populate the account completion form on the public site.
Expand Down
4 changes: 1 addition & 3 deletions api/test/unit/services/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1062,9 +1062,7 @@ describe('Testing auth service', () => {
},
response as unknown as Response,
),
).rejects.toThrowError(
`resetToken ${token} does not match user ${secondId}'s reset token (${secondToken})`,
);
).rejects.toThrowError(`tokenExpired`);

expect(prisma.userAccounts.update).not.toHaveBeenCalled();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ locals {
S3_PRIVATE_BUCKET = aws_s3_bucket.private.id
S3_PUBLIC_BUCKET = aws_s3_bucket.public.id
OTEL_EXPORTER_OTLP_ENDPOINT = "http://127.0.0.1:4317"
USE_WINSTON = "TRUE"
}
}
resource "aws_ecs_task_definition" "bloom_api" {
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "الرجاء إدخال كلمة المرور الجديدة لتسجيل الدخول",
"authentication.forgotPassword.errors.emailNotFound": "البريد الإلكتروني غير موجود. يرجى التأكد من أن بريدك الإلكتروني لديه حساب معنا وأنه تم تأكيده.",
"authentication.forgotPassword.errors.passwordTooWeak": "كلمة المرور ضعيفة جدًا. يجب ألا تقل عن ١٢ حرفًا، وأن تتضمن على الأقل حرفًا صغيرًا واحدًا، وحرفًا كبيرًا واحدًا، ورقمًا واحدًا، ورمزًا خاصًا واحدًا (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "انتهت صلاحية رمز إعادة تعيين كلمة المرور. الرجاء طلب واحدة جديدة.",
"authentication.forgotPassword.errors.tokenMissing": "لم يتم العثور على الرمز. الرجاء طلب واحدة جديدة.",
"authentication.forgotPassword.errors.tokenExpired": "لقد انتهت صلاحية رابط إعادة تعيين كلمة المرور. يرجى طلب رابط جديد.",
"authentication.forgotPassword.errors.tokenMissing": "رابط إعادة تعيين كلمة المرور غير صالح. يرجى طلب رابط جديد.",
"authentication.forgotPassword.message": "إذا كان هناك حساب تم إنشاؤه باستخدام هذا البريد الإلكتروني ، فستتلقى بريدًا إلكترونيًا به ارتباط لإعادة تعيين كلمة المرور الخاصة بك.",
"authentication.forgotPassword.passwordConfirmation": "تأكيد كلمة المرور",
"authentication.forgotPassword.sendEmail": "أدخل بريدك الإلكتروني للحصول على رابط إعادة تعيين كلمة المرور",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/bn.json
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "অনুগ্রহ করে নতুন লগইন পাসওয়ার্ড লিখুন।",
"authentication.forgotPassword.errors.emailNotFound": "ইমেল পাওয়া যায়নি। অনুগ্রহ করে নিশ্চিত করুন যে আপনার ইমেলের আমাদের সাথে একটি অ্যাকাউন্ট আছে এবং নিশ্চিত করা হয়েছে।",
"authentication.forgotPassword.errors.passwordTooWeak": "পাসওয়ার্ডটি খুবই দুর্বল। কমপক্ষে ১২টি অক্ষরের হতে হবে এবং কমপক্ষে একটি ছোট হাতের অক্ষর, একটি বড় হাতের অক্ষর, একটি সংখ্যা এবং একটি বিশেষ অক্ষর (#?!@$%^&*-) অন্তর্ভুক্ত থাকতে হবে।",
"authentication.forgotPassword.errors.tokenExpired": "পাসওয়ার্ড টোকেনের মেয়াদ শেষ হয়ে গেছে। অনুগ্রহ করে নতুনের জন্য অনুরোধ করুন।",
"authentication.forgotPassword.errors.tokenMissing": "টোকেন পাওয়া যায়নি। অনুগ্রহ করে নতুনের জন্য অনুরোধ করুন।",
"authentication.forgotPassword.errors.tokenExpired": "পাসওয়ার্ড রিসেট করার লিঙ্কের মেয়াদ শেষ হয়ে গেছে। অনুগ্রহ করে নতুন একটি লিঙ্কের জন্য অনুরোধ করুন।",
"authentication.forgotPassword.errors.tokenMissing": "পাসওয়ার্ড রিসেট করার লিঙ্কটি ত্রুটিপূর্ণ। অনুগ্রহ করে নতুন একটি লিঙ্ক অনুরোধ করুন।",
"authentication.forgotPassword.message": "যদি সেই ইমেল দিয়ে একটি অ্যাকাউন্ট তৈরি করা হয়, তাহলে আপনি আপনার পাসওয়ার্ড রিসেট করার জন্য একটি লিঙ্ক সহ একটি ইমেল পাবেন।",
"authentication.forgotPassword.passwordConfirmation": "পাসওয়ার্ড নিশ্চিতকরণ",
"authentication.forgotPassword.sendEmail": "পাসওয়ার্ড রিসেট লিঙ্ক পেতে আপনার ইমেল ঠিকানা লিখুন",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "Por favor ingrese una nueva contraseña de inicio de sesión",
"authentication.forgotPassword.errors.emailNotFound": "El correo electrónico no fue encontrado. Por favor, revise que si ha creado una cuenta con nosotros con ese correo electrónico y haya sido confirmado confirmado.",
"authentication.forgotPassword.errors.passwordTooWeak": "La contraseña es demasiado débil. Debe tener al menos 12 caracteres e incluir al menos una letra minúscula, una letra mayúscula, un número y un carácter especial (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "El token de restablecimiento de contraseña caducó. Por favor, solicite uno nuevo.",
"authentication.forgotPassword.errors.tokenMissing": "El token no fue encontrado. Por favor, solicite uno nuevo.",
"authentication.forgotPassword.errors.tokenExpired": "El enlace para restablecer la contraseña ha caducado. Por favor, solicite uno nuevo.",
"authentication.forgotPassword.errors.tokenMissing": "El enlace para restablecer la contraseña no es válido. Por favor, solicite uno nuevo.",
"authentication.forgotPassword.message": "Si hay una cuenta creada con ese correo electrónico, recibirás un correo electrónico con un enlace para restablecer tu contraseña. El enlace de reinicio es válido por 1 hora.",
"authentication.forgotPassword.passwordConfirmation": "Confirmación de contraseña",
"authentication.forgotPassword.sendEmail": "Ingrese su correo electrónico para obtener un enlace de restablecimiento de contraseña",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/fa.json
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "لطفا رمز عبور جدید ورود را وارد کنید",
"authentication.forgotPassword.errors.emailNotFound": "ایمیل پیدا نشد. لطفاً مطمئن شوید که ایمیل شما دارای حساب کاربری در ما است و تأیید شده است.",
"authentication.forgotPassword.errors.passwordTooWeak": "رمز عبور خیلی ضعیف است. باید حداقل ۱۲ کاراکتر داشته باشد و شامل حداقل یک حرف کوچک، یک حرف بزرگ، یک عدد و یک کاراکتر ویژه (#?!@$%^&amp;*-) باشد.",
"authentication.forgotPassword.errors.tokenExpired": "رمز عبور جدید منقضی شده است. لطفا رمز عبور جدید درخواست کنید.",
"authentication.forgotPassword.errors.tokenMissing": "توکن پیدا نشد. لطفا درخواست توکن جدید بدهید.",
"authentication.forgotPassword.errors.tokenExpired": "لینک بازیابی رمز عبور منقضی شده است. لطفا درخواست رمز جدید دهید.",
"authentication.forgotPassword.errors.tokenMissing": "لینک بازیابی رمز عبور ناقص است. لطفا درخواست رمز جدید دهید.",
"authentication.forgotPassword.message": "اگر با آن ایمیل حساب کاربری ساخته شده باشد، ایمیلی حاوی لینکی برای تنظیم مجدد رمز عبور دریافت خواهید کرد. لینک تنظیم مجدد به مدت ۱ ساعت معتبر است.",
"authentication.forgotPassword.passwordConfirmation": "تأیید رمز عبور",
"authentication.forgotPassword.sendEmail": "ایمیل خود را وارد کنید تا لینک بازنشانی رمز عبور را دریافت کنید",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/general.json
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "Please enter new login password",
"authentication.forgotPassword.errors.emailNotFound": "Email not found. Please make sure your email has an account with us and is confirmed.",
"authentication.forgotPassword.errors.passwordTooWeak": "Password is too weak. Must be at least 12 characters and include at least one lowercase letter, one uppercase letter, one number, and one special character (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "Reset password token expired. Please request for a new one.",
"authentication.forgotPassword.errors.tokenMissing": "Token not found. Please request for a new one.",
"authentication.forgotPassword.errors.tokenExpired": "Reset password link expired. Please request a new one.",
"authentication.forgotPassword.errors.tokenMissing": "Reset password link is malformed. Please request a new one.",
"authentication.forgotPassword.message": "If there is an account made with that email, you'll receive an email with a link to reset your password. The reset link is valid for 1 hour.",
"authentication.forgotPassword.passwordConfirmation": "Password confirmation",
"authentication.forgotPassword.sendEmail": "Enter your email to get a password reset link",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/hy.json
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "Խնդրում ենք մուտքագրել նոր մուտքի գաղտնաբառը",
"authentication.forgotPassword.errors.emailNotFound": "Էլ․ հասցեն չի գտնվել։ Համոզվեք, որ ձեր էլ․ հասցեն մեզ մոտ հաշիվ ունի և հաստատված է։",
"authentication.forgotPassword.errors.passwordTooWeak": "Գաղտնաբառը չափազանց թույլ է։ Պետք է լինի առնվազն 12 նիշ և պարունակի առնվազն մեկ փոքրատառ, մեկ մեծատառ, մեկ թիվ և մեկ հատուկ նիշ (#?!@$%^&amp;*-):",
"authentication.forgotPassword.errors.tokenExpired": "Գաղտնաբառի վերակայման տոկենի ժամկետը լրացել է։ Խնդրում ենք նորը խնդրել։",
"authentication.forgotPassword.errors.tokenMissing": "Թոքենը չի գտնվել։ Խնդրում ենք նորը խնդրել։",
"authentication.forgotPassword.errors.tokenExpired": "Գաղտնաբառի վերականգնման հղումը ժամկետանց է։ Խնդրում ենք նորը խնդրել։",
"authentication.forgotPassword.errors.tokenMissing": "Գաղտնաբառի վերակայման հղումը սխալ է։ Խնդրում ենք նորը խնդրել։",
"authentication.forgotPassword.message": "Եթե այդ էլ․ հասցեով հաշիվ է ստեղծվել, դուք կստանաք էլ․ նամակ՝ ձեր գաղտնաբառը վերականգնելու հղումով։ Վերականգնման հղումը վավեր է 1 ժամ։",
"authentication.forgotPassword.passwordConfirmation": "Գաղտնաբառի հաստատում",
"authentication.forgotPassword.sendEmail": "Մուտքագրեք ձեր էլ․ հասցեն՝ գաղտնաբառի վերականգնման հղումը ստանալու համար",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "새 로그인 비밀번호를 입력하세요.",
"authentication.forgotPassword.errors.emailNotFound": "이메일을 찾을 수 없습니다. 귀하의 이메일 주소가 당사에 등록된 계정이며 인증되었는지 확인해 주십시오.",
"authentication.forgotPassword.errors.passwordTooWeak": "비밀번호가 너무 취약합니다. 비밀번호는 최소 12자 이상이어야 하며, 소문자, 대문자, 숫자, 특수 문자(#?!@$%^&amp;*-)를 각각 하나씩 포함해야 합니다.",
"authentication.forgotPassword.errors.tokenExpired": "비밀번호 재설정 토큰이 만료되었습니다. 새 토큰을 요청해 주세요.",
"authentication.forgotPassword.errors.tokenMissing": "토큰을 찾을 수 없습니다. 새 토큰을 요청해 주세요.",
"authentication.forgotPassword.errors.tokenExpired": "비밀번호 재설정 링크가 만료되었습니다. 새 링크를 요청해 주세요.",
"authentication.forgotPassword.errors.tokenMissing": "비밀번호 재설정 링크 형식이 올바르지 않습니다. 새 링크를 요청해 주세요.",
"authentication.forgotPassword.message": "해당 이메일 주소로 계정이 있는 경우, 비밀번호 재설정 링크가 포함된 이메일을 받게 됩니다. 재설정 링크는 1시간 동안 유효합니다.",
"authentication.forgotPassword.passwordConfirmation": "비밀번호 확인",
"authentication.forgotPassword.sendEmail": "이메일 주소를 입력하시면 비밀번호 재설정 링크를 받으실 수 있습니다.",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/tl.json
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "Mangyaring magpasok ng bagong password sa pag-login",
"authentication.forgotPassword.errors.emailNotFound": "Hindi nahanap ang email. Pakitiyak na ang iyong email ay may account sa amin at nakumpirma.",
"authentication.forgotPassword.errors.passwordTooWeak": "Masyadong mahina ang password. Dapat ay hindi bababa sa 12 character at may kasamang hindi bababa sa isang maliit na titik, isang malaking titik, isang numero, at isang espesyal na character (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "Nag-expire na ang token ng pag-reset ng password. Humiling ng bago.",
"authentication.forgotPassword.errors.tokenMissing": "Hindi nahanap ang token. Humiling ng bago.",
"authentication.forgotPassword.errors.tokenExpired": "Nag-expire ang link sa pag-reset ng password. Mangyaring humiling ng bago.",
"authentication.forgotPassword.errors.tokenMissing": "Mali ang pagkakabuo ng link sa pag-reset ng password. Mangyaring humiling ng bago.",
"authentication.forgotPassword.message": "Kung may account na ginawa gamit ang email na iyon, makakatanggap ka ng email na may link para i-reset ang iyong password. Ang link sa pag-reset ay may bisa sa loob ng 1 oras.",
"authentication.forgotPassword.passwordConfirmation": "Pagkumpirma ng password",
"authentication.forgotPassword.sendEmail": "Ilagay ang iyong email para makakuha ng link sa pag-reset ng password",
Expand Down
4 changes: 2 additions & 2 deletions shared-helpers/src/locales/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,8 @@
"authentication.forgotPassword.enterNewLoginPassword": "Vui lòng nhập mật khẩu đăng nhập mới",
"authentication.forgotPassword.errors.emailNotFound": "Không tìm thấy email. Vui lòng đảm bảo email của quý vị có tài khoản với chúng tôi và đã được xác nhận.",
"authentication.forgotPassword.errors.passwordTooWeak": "Mật khẩu quá yếu. Phải có ít nhất 12 ký tự và bao gồm ít nhất một chữ cái viết thường, một chữ cái viết hoa, một số và một ký tự đặc biệt (#?!@$%^&*-).",
"authentication.forgotPassword.errors.tokenExpired": "Mã thông báo đặt lại mật khẩu đã hết hạn. Vui lòng yêu cầu mới.",
"authentication.forgotPassword.errors.tokenMissing": "Không tìm thấy mã thông báo. Vui lòng yêu cầu mới.",
"authentication.forgotPassword.errors.tokenExpired": "Liên kết đặt lại mật khẩu đã hết hạn. Vui lòng yêu cầu một liên kết mới.",
"authentication.forgotPassword.errors.tokenMissing": "Liên kết đặt lại mật khẩu không hợp lệ. Vui lòng yêu cầu một liên kết mới.",
"authentication.forgotPassword.message": "Nếu có tài khoản được tạo bằng email đó, bạn sẽ nhận được email có liên kết để đặt lại mật khẩu của mình. Liên kết đặt lại có hiệu lực trong 1 giờ.",
"authentication.forgotPassword.passwordConfirmation": "Xác nhận mật khẩu",
"authentication.forgotPassword.sendEmail": "Nhập email của bạn để nhận liên kết đặt lại mật khẩu",
Expand Down
Loading
Loading