Просмотр исходного кода

Enhance expiration date validation by normalizing time portions for accurate comparisons

reiji-h 1 год назад
Родитель
Сommit
97b773cc9d

+ 4 - 1
apps/app/src/client/components/Me/AccessTokenForm.tsx

@@ -71,7 +71,10 @@ export const AccessTokenForm = React.memo((props: AccessTokenFormProps): JSX.Ele
                       validate: (value) => {
                       validate: (value) => {
                         const date = new Date(value);
                         const date = new Date(value);
                         const now = new Date();
                         const now = new Date();
-                        return date > now || 'Expiration date must be in the future';
+                        // Reset time portions to compare dates only
+                        date.setHours(0, 0, 0, 0);
+                        now.setHours(0, 0, 0, 0);
+                        return date >= now || 'Expiration date must be in the future';
                       },
                       },
                     })}
                     })}
                   />
                   />

+ 9 - 4
apps/app/src/server/models/access-token.ts

@@ -15,6 +15,11 @@ import { getOrCreateModel } from '../util/mongoose-utils';
 const logger = loggerFactory('growi:models:access-token');
 const logger = loggerFactory('growi:models:access-token');
 
 
 const generateTokenHash = (token: string) => crypto.createHash('sha256').update(token).digest('hex');
 const generateTokenHash = (token: string) => crypto.createHash('sha256').update(token).digest('hex');
+const getNowDate = () => {
+  const now = new Date();
+  now.setHours(0, 0, 0, 0);
+  return now;
+};
 
 
 type GenerateTokenResult = {
 type GenerateTokenResult = {
   token: string,
   token: string,
@@ -95,24 +100,24 @@ accessTokenSchema.statics.deleteAllTokensByUserId = async function(userId: Types
 };
 };
 
 
 accessTokenSchema.statics.deleteExpiredToken = async function() {
 accessTokenSchema.statics.deleteExpiredToken = async function() {
-  const now = new Date();
+  const now = getNowDate();
   await this.deleteMany({ expiredAt: { $lt: now } });
   await this.deleteMany({ expiredAt: { $lt: now } });
 };
 };
 
 
 accessTokenSchema.statics.findUserIdByToken = async function(token: string) {
 accessTokenSchema.statics.findUserIdByToken = async function(token: string) {
   const tokenHash = generateTokenHash(token);
   const tokenHash = generateTokenHash(token);
-  const now = new Date();
+  const now = getNowDate();
   return this.findOne({ tokenHash, expiredAt: { $gte: now } }).select('user');
   return this.findOne({ tokenHash, expiredAt: { $gte: now } }).select('user');
 };
 };
 
 
 accessTokenSchema.statics.findTokenByUserId = async function(userId: Types.ObjectId | string) {
 accessTokenSchema.statics.findTokenByUserId = async function(userId: Types.ObjectId | string) {
-  const now = new Date();
+  const now = getNowDate();
   return this.find({ user: userId, expiredAt: { $gte: now } }).select('_id expiredAt scope description');
   return this.find({ user: userId, expiredAt: { $gte: now } }).select('_id expiredAt scope description');
 };
 };
 
 
 accessTokenSchema.statics.validateTokenScopes = async function(token: string, requiredScopes: string[]) {
 accessTokenSchema.statics.validateTokenScopes = async function(token: string, requiredScopes: string[]) {
   const tokenHash = generateTokenHash(token);
   const tokenHash = generateTokenHash(token);
-  const now = new Date();
+  const now = getNowDate();
   const tokenData = await this.findOne({ tokenHash, expiredAt: { $gte: now }, scope: { $all: requiredScopes } });
   const tokenData = await this.findOne({ tokenHash, expiredAt: { $gte: now }, scope: { $all: requiredScopes } });
   return tokenData != null;
   return tokenData != null;
 };
 };

+ 4 - 1
apps/app/src/server/routes/apiv3/personal-setting/generate-access-token.ts

@@ -36,13 +36,16 @@ const validator = [
       const expiredAt = new Date(value);
       const expiredAt = new Date(value);
       const now = new Date();
       const now = new Date();
 
 
+      expiredAt.setHours(0, 0, 0, 0);
+      now.setHours(0, 0, 0, 0);
+
       // Check if date is valid
       // Check if date is valid
       if (Number.isNaN(expiredAt.getTime())) {
       if (Number.isNaN(expiredAt.getTime())) {
         throw new Error('Invalid date format');
         throw new Error('Invalid date format');
       }
       }
 
 
       // Check if date is in the future
       // Check if date is in the future
-      if (expiredAt <= now) {
+      if (expiredAt < now) {
         throw new Error('Expiration date must be in the future');
         throw new Error('Expiration date must be in the future');
       }
       }