fix: managed user timeZone, timeFormat and weekStart during creation (#14955)

* refactor: create, update user inputs use types instead of custom validators

* fix: save weekStart, timeFormat, timeZone when creating user

* fix: save weekStart, timeFormat, timeZone when creating user

* e2e: fix env variables and test weekStart, timeZone and timeFormat during user create
This commit is contained in:
Lauris Skraucis
2024-05-09 10:25:14 -03:00
committed by GitHub
parent 2f5768b74f
commit b8890c841c
10 changed files with 80 additions and 64 deletions
@@ -139,6 +139,8 @@ describe("OAuth Client Users Endpoints", () => {
const requestBody: CreateManagedUserInput = {
email: userEmail,
timeZone: userTimeZone,
weekStart: "Monday",
timeFormat: 24,
};
const response = await request(app.getHttpServer())
@@ -158,6 +160,9 @@ describe("OAuth Client Users Endpoints", () => {
expect(responseBody.status).toEqual(SUCCESS_STATUS);
expect(responseBody.data).toBeDefined();
expect(responseBody.data.user.email).toEqual(getOAuthUserEmail(oAuthClient.id, requestBody.email));
expect(responseBody.data.user.timeZone).toEqual(requestBody.timeZone);
expect(responseBody.data.user.weekStart).toEqual(requestBody.weekStart);
expect(responseBody.data.user.timeFormat).toEqual(requestBody.timeFormat);
expect(responseBody.data.accessToken).toBeDefined();
expect(responseBody.data.refreshToken).toBeDefined();
@@ -53,6 +53,9 @@ export class OAuthClientUsersService {
},
},
isPlatformManaged,
timeFormat: body.timeFormat,
weekStart: body.weekStart,
timeZone: body.timeZone,
})
)[0];
await this.userRepository.addToOAuthClient(user.id, oAuthClientId);
@@ -1,8 +1,8 @@
import { IsTimeFormat } from "@/modules/users/inputs/validators/is-time-format";
import { IsWeekStart } from "@/modules/users/inputs/validators/is-week-start";
import { ApiProperty } from "@nestjs/swagger";
import { IsNumber, IsOptional, IsTimeZone, IsString, Validate } from "class-validator";
import { IsOptional, IsTimeZone, IsString } from "class-validator";
export type WeekDay = "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday";
export type TimeFormat = 12 | 24;
export class CreateManagedUserInput {
@IsString()
@ApiProperty({ example: "alice@example.com" })
@@ -12,17 +12,17 @@ export class CreateManagedUserInput {
@IsOptional()
name?: string;
@IsNumber()
@IsOptional()
@Validate(IsTimeFormat)
@ApiProperty({ example: 12 })
timeFormat?: number;
@ApiProperty({ example: 12, enum: [12, 24], description: "Must be 12 or 24" })
timeFormat?: TimeFormat;
@IsString()
@IsOptional()
@Validate(IsWeekStart)
@ApiProperty({ example: "Sunday" })
weekStart?: string;
@IsString()
@ApiProperty({
example: "Monday",
enum: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
})
weekStart?: WeekDay;
@IsTimeZone()
@IsOptional()
@@ -1,6 +1,6 @@
import { IsTimeFormat } from "@/modules/users/inputs/validators/is-time-format";
import { IsWeekStart } from "@/modules/users/inputs/validators/is-week-start";
import { IsNumber, IsOptional, IsString, IsTimeZone, Validate } from "class-validator";
import { TimeFormat, WeekDay } from "@/modules/users/inputs/create-managed-user.input";
import { ApiProperty } from "@nestjs/swagger";
import { IsNumber, IsOptional, IsString, IsTimeZone } from "class-validator";
export class UpdateManagedUserInput {
@IsString()
@@ -11,19 +11,21 @@ export class UpdateManagedUserInput {
@IsOptional()
name?: string;
@IsNumber()
@IsOptional()
@Validate(IsTimeFormat)
timeFormat?: number;
@ApiProperty({ example: 12, enum: [12, 24], description: "Must be 12 or 24" })
timeFormat?: TimeFormat;
@IsNumber()
@IsOptional()
defaultScheduleId?: number;
@IsString()
@IsOptional()
@Validate(IsWeekStart)
weekStart?: string;
@IsString()
@ApiProperty({
example: "Monday",
enum: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
})
weekStart?: WeekDay;
@IsTimeZone()
@IsOptional()
@@ -1,12 +0,0 @@
import { ValidatorConstraint, ValidatorConstraintInterface } from "class-validator";
@ValidatorConstraint({ name: "isTimeFormat", async: false })
export class IsTimeFormat implements ValidatorConstraintInterface {
validate(timeFormat: number) {
return timeFormat === 12 || timeFormat === 24;
}
defaultMessage() {
return "timeFormat must be a number either 12 or 24";
}
}
@@ -1,23 +0,0 @@
import { ValidatorConstraint, ValidatorConstraintInterface } from "class-validator";
@ValidatorConstraint({ name: "isWeekStart", async: false })
export class IsWeekStart implements ValidatorConstraintInterface {
validate(weekStart: string) {
if (!weekStart) return false;
const lowerCaseWeekStart = weekStart.toLowerCase();
return (
lowerCaseWeekStart === "monday" ||
lowerCaseWeekStart === "tuesday" ||
lowerCaseWeekStart === "wednesday" ||
lowerCaseWeekStart === "thursday" ||
lowerCaseWeekStart === "friday" ||
lowerCaseWeekStart === "saturday" ||
lowerCaseWeekStart === "sunday"
);
}
defaultMessage() {
return "weekStart must be a string either Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, or Sunday";
}
}
@@ -157,7 +157,7 @@ export class UsersRepository {
formatInput(userInput: CreateManagedUserInput | UpdateManagedUserInput) {
if (userInput.weekStart) {
userInput.weekStart = capitalize(userInput.weekStart);
userInput.weekStart = userInput.weekStart;
}
if (userInput.timeZone) {
+38 -8
View File
@@ -1651,11 +1651,25 @@
},
"timeFormat": {
"type": "number",
"example": 12
"example": 12,
"enum": [
12,
24
],
"description": "Must be 12 or 24"
},
"weekStart": {
"type": "string",
"example": "Sunday"
"example": "Monday",
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
]
},
"timeZone": {
"type": "string",
@@ -1731,21 +1745,37 @@
"UpdateManagedUserInput": {
"type": "object",
"properties": {
"timeFormat": {
"type": "number",
"example": 12,
"enum": [
12,
24
],
"description": "Must be 12 or 24"
},
"weekStart": {
"type": "string",
"example": "Monday",
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
]
},
"email": {
"type": "string"
},
"name": {
"type": "string"
},
"timeFormat": {
"type": "number"
},
"defaultScheduleId": {
"type": "number"
},
"weekStart": {
"type": "string"
},
"timeZone": {
"type": "string"
}
+2
View File
@@ -8,6 +8,8 @@ const env: Partial<Omit<Environment, "NODE_ENV">> = {
JWT_SECRET: "XF+Hws3A5g2eyWA5uGYYVJ74X+wrCWJ8oWo6kAfU6O8=",
LOG_LEVEL: "trace",
REDIS_URL: "redis://localhost:9199",
STRIPE_API_KEY: "sk_test_51J4",
STRIPE_WEBHOOK_SECRET: "whsec_51J4",
};
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
@@ -215,6 +215,9 @@ export async function createNewUsersConnectToOrgIfExists({
autoAcceptEmailDomain,
connectionInfoMap,
isPlatformManaged,
timeFormat,
weekStart,
timeZone,
}: {
usernamesOrEmails: string[];
input: InviteMemberOptions["input"];
@@ -222,6 +225,9 @@ export async function createNewUsersConnectToOrgIfExists({
autoAcceptEmailDomain?: string;
connectionInfoMap: Record<string, ReturnType<typeof getOrgConnectionInfo>>;
isPlatformManaged?: boolean;
timeFormat?: number;
weekStart?: string;
timeZone?: string;
}) {
// fail if we have invalid emails
usernamesOrEmails.forEach((usernameOrEmail) => checkInputEmailIsValid(usernameOrEmail));
@@ -253,6 +259,9 @@ export async function createNewUsersConnectToOrgIfExists({
verified: true,
invitedTo: input.teamId,
isPlatformManaged: !!isPlatformManaged,
timeFormat,
weekStart,
timeZone,
organizationId: orgId || null, // If the user is invited to a child team, they are automatically added to the parent org
...(orgId
? {