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:
+5
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user