Browse Source

Fix date handling in time zone other than UTC

pull/7723/head
Thomas Kaul 3 days ago
parent
commit
9b18afd9c3
  1. 2
      apps/api/src/app/user/user.service.ts
  2. 25
      apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts
  3. 2
      apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html
  4. 4
      libs/common/src/lib/dtos/create-access.dto.ts
  5. 9
      libs/common/src/lib/dtos/update-access.dto.ts

2
apps/api/src/app/user/user.service.ts

@ -138,7 +138,7 @@ export class UserService {
user: true user: true
}, },
orderBy: { alias: 'asc' }, orderBy: { alias: 'asc' },
where: { expiresAt: { gt: new Date() }, granteeUserId: id } where: { granteeUserId: id }
}), }),
this.prismaService.account.findMany({ this.prismaService.account.findMany({
include: { platform: true }, include: { platform: true },

25
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts

@ -52,7 +52,7 @@ import {
import { MatFormFieldModule } from '@angular/material/form-field'; import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input'; import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select';
import { addYears, endOfDay, isBefore, startOfDay } from 'date-fns'; import { addYears, endOfDay, isBefore, isValid, startOfDay } from 'date-fns';
import { StatusCodes } from 'http-status-codes'; import { StatusCodes } from 'http-status-codes';
import { EMPTY, catchError } from 'rxjs'; import { EMPTY, catchError } from 'rxjs';
@ -84,6 +84,7 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
public tags: Filter[] = []; public tags: Filter[] = [];
protected accessForm: FormGroup; protected accessForm: FormGroup;
protected minExpiresAt: Date;
protected readonly mode: 'create' | 'update'; protected readonly mode: 'create' | 'update';
protected readonly today = startOfDay(new Date()); protected readonly today = startOfDay(new Date());
@ -153,9 +154,10 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
] ]
}); });
if (access?.expiresAt && isBefore(new Date(access.expiresAt), this.today)) { this.minExpiresAt =
this.accessForm.get('expiresAt')?.markAsTouched(); access?.expiresAt && isBefore(new Date(access.expiresAt), this.today)
} ? startOfDay(new Date(access.expiresAt))
: this.today;
this.assetClasses = getAssetClassFilters(); this.assetClasses = getAssetClassFilters();
@ -223,9 +225,20 @@ export class GfCreateOrUpdateAccessDialogComponent implements OnInit {
} }
private buildExpiresAt() { private buildExpiresAt() {
const expiresAt = this.accessForm.get('expiresAt')?.value as Date; const expiresAtControl = this.accessForm.get('expiresAt');
const expiresAtOfAccess = this.data.access?.expiresAt;
if (
this.mode === 'update' &&
!expiresAtControl?.dirty &&
expiresAtOfAccess
) {
return new Date(expiresAtOfAccess).toISOString();
}
const expiresAt = expiresAtControl?.value as Date;
return endOfDay(expiresAt).toISOString(); return isValid(expiresAt) ? endOfDay(expiresAt).toISOString() : '';
} }
private buildFilters(): Filter[] { private buildFilters(): Filter[] {

2
apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html

@ -52,7 +52,7 @@
formControlName="expiresAt" formControlName="expiresAt"
matInput matInput
[matDatepicker]="expiresAt" [matDatepicker]="expiresAt"
[min]="today" [min]="minExpiresAt"
/> />
<mat-datepicker-toggle class="mr-2" matSuffix [for]="expiresAt"> <mat-datepicker-toggle class="mr-2" matSuffix [for]="expiresAt">
<ion-icon <ion-icon

4
libs/common/src/lib/dtos/create-access.dto.ts

@ -5,9 +5,9 @@ import { IsInTheFutureConstraint } from '@ghostfolio/common/validator-constraint
import { AccessType } from '@prisma/client'; import { AccessType } from '@prisma/client';
import { import {
IsArray, IsArray,
IsDateString,
IsEnum, IsEnum,
IsIn, IsIn,
IsISO8601,
IsOptional, IsOptional,
IsString, IsString,
IsUUID, IsUUID,
@ -19,7 +19,7 @@ export class CreateAccessDto {
@IsString() @IsString()
alias?: string; alias?: string;
@IsDateString() @IsISO8601()
@Validate(IsInTheFutureConstraint) @Validate(IsInTheFutureConstraint)
expiresAt: string; expiresAt: string;

9
libs/common/src/lib/dtos/update-access.dto.ts

@ -1,15 +1,13 @@
import { Filter } from '@ghostfolio/common/interfaces'; import { Filter } from '@ghostfolio/common/interfaces';
import { Scope, scopes } from '@ghostfolio/common/scopes'; import { Scope, scopes } from '@ghostfolio/common/scopes';
import { IsInTheFutureConstraint } from '@ghostfolio/common/validator-constraints/is-in-the-future';
import { import {
IsArray, IsArray,
IsDateString,
IsIn, IsIn,
IsISO8601,
IsOptional, IsOptional,
IsString, IsString,
IsUUID, IsUUID
Validate
} from 'class-validator'; } from 'class-validator';
export class UpdateAccessDto { export class UpdateAccessDto {
@ -17,8 +15,7 @@ export class UpdateAccessDto {
@IsString() @IsString()
alias?: string; alias?: string;
@IsDateString() @IsISO8601()
@Validate(IsInTheFutureConstraint)
expiresAt: string; expiresAt: string;
@IsArray() @IsArray()

Loading…
Cancel
Save