Explorar o código

Merge branch 'feat/enhanced-access-token' into feat/85969-85966-access-token-parser-use-access-token-model

reiji-h hai 1 ano
pai
achega
7f5eeebdd3
Modificáronse 1 ficheiros con 24 adicións e 29 borrados
  1. 24 29
      apps/app/src/server/models/access-token.ts

+ 24 - 29
apps/app/src/server/models/access-token.ts

@@ -1,5 +1,6 @@
 import crypto from 'crypto';
 
+import type { Ref, IUserHasId } from '@growi/core/dist/interfaces';
 import type { Document, Model, Types } from 'mongoose';
 import { Schema } from 'mongoose';
 import mongoosePaginate from 'mongoose-paginate-v2';
@@ -9,25 +10,19 @@ import loggerFactory from '~/utils/logger';
 
 import { getOrCreateModel } from '../util/mongoose-utils';
 
-const logger = loggerFactory('growi:models:comment');
+const logger = loggerFactory('growi:models:access-token');
 
 const generateTokenHash = (token: string) => crypto.createHash('sha256').update(token).digest('hex');
 
 export type IAccessToken = {
-  userId: Types.ObjectId,
+  user: Ref<IUserHasId>,
   tokenHash: string,
   expiredAt: Date,
-  scope: string[],
-  description: string,
+  scope?: string[],
+  description?: string,
 }
 
 export interface IAccessTokenDocument extends IAccessToken, Document {
-  userId: Types.ObjectId,
-  tokenHash: string,
-  expiredAt: Date,
-  scope: string[],
-  description: string,
-
   isExpired: () => boolean
 }
 
@@ -37,13 +32,13 @@ export interface IAccessTokenModel extends Model<IAccessTokenDocument> {
   deleteTokenById: (tokenId: Types.ObjectId) => Promise<void>
   deleteAllTokensByUserId: (userId: Types.ObjectId) => Promise<void>
   deleteExpiredToken: () => Promise<void>
-  findUserIdByToken: (token: string) => Promise<IAccessTokenDocument>
+  findUserIdByToken: (token: string) => Promise<Types.ObjectId>
   findTokenByUserId: (userId: Types.ObjectId) => Promise<IAccessTokenDocument[]>
   validateTokenScopes: (token: string, requiredScope: string[]) => Promise<boolean>
 }
 
-const IAccessTokenSchema = new Schema<IAccessTokenDocument, IAccessTokenModel>({
-  userId: {
+const accessTokenSchema = new Schema<IAccessTokenDocument, IAccessTokenModel>({
+  user: {
     type: Schema.Types.ObjectId, ref: 'User', required: true,
   },
   tokenHash: { type: String, required: true, unique: true },
@@ -52,17 +47,17 @@ const IAccessTokenSchema = new Schema<IAccessTokenDocument, IAccessTokenModel>({
   description: { type: String, default: '' },
 });
 
-IAccessTokenSchema.plugin(mongoosePaginate);
-IAccessTokenSchema.plugin(uniqueValidator);
+accessTokenSchema.plugin(mongoosePaginate);
+accessTokenSchema.plugin(uniqueValidator);
 
-IAccessTokenSchema.statics.generateToken = async function(userId: Types.ObjectId, expiredAt: Date, scope?: string[], description?: string) {
+accessTokenSchema.statics.generateToken = async function(userId: Types.ObjectId, expiredAt: Date, scope?: string[], description?: string) {
 
   const token = crypto.randomBytes(32).toString('hex');
   const tokenHash = generateTokenHash(token);
 
   try {
     const { _id } = await this.create({
-      userId, tokenHash, expiredAt, scope, description,
+      user: userId, tokenHash, expiredAt, scope, description,
     });
 
     logger.debug('Token generated');
@@ -76,44 +71,44 @@ IAccessTokenSchema.statics.generateToken = async function(userId: Types.ObjectId
   }
 };
 
-IAccessTokenSchema.statics.deleteToken = async function(token: string) {
+accessTokenSchema.statics.deleteToken = async function(token: string) {
   const tokenHash = generateTokenHash(token);
   return this.deleteOne({ tokenHash });
 };
 
-IAccessTokenSchema.statics.deleteTokenById = async function(tokenId: Types.ObjectId) {
+accessTokenSchema.statics.deleteTokenById = async function(tokenId: Types.ObjectId) {
   return this.deleteOne({ _id: tokenId });
 };
 
-IAccessTokenSchema.statics.deleteAllTokensByUserId = async function(userId: Types.ObjectId) {
-  return this.deleteMany({ userId });
+accessTokenSchema.statics.deleteAllTokensByUserId = async function(userId: Types.ObjectId) {
+  return this.deleteMany({ user: userId });
 };
 
-IAccessTokenSchema.statics.deleteExpiredToken = async function() {
+accessTokenSchema.statics.deleteExpiredToken = async function() {
   const now = new Date();
   return this.deleteMany({ expiredAt: { $lte: now } });
 };
 
-IAccessTokenSchema.statics.findUserIdByToken = async function(token: string) {
+accessTokenSchema.statics.findUserIdByToken = async function(token: string) {
   const tokenHash = generateTokenHash(token);
   const now = new Date();
-  return this.findOne({ tokenHash, expiredAt: { $gt: now } }).select('userId');
+  return this.findOne({ tokenHash, expiredAt: { $gt: now } }).select('user');
 };
 
-IAccessTokenSchema.statics.findTokenByUserId = async function(userId: Types.ObjectId) {
+accessTokenSchema.statics.findTokenByUserId = async function(userId: Types.ObjectId) {
   const now = new Date();
-  return this.find({ userId, expiredAt: { $gt: now } }).select('_id expiredAt scope description');
+  return this.find({ user: userId, expiredAt: { $gt: now } }).select('_id expiredAt scope description');
 };
 
-IAccessTokenSchema.statics.validateTokenScopes = async function(token: string, requiredScopes: string[]) {
+accessTokenSchema.statics.validateTokenScopes = async function(token: string, requiredScopes: string[]) {
   const tokenHash = generateTokenHash(token);
   const now = new Date();
   const tokenData = await this.findOne({ tokenHash, expiredAt: { $gt: now }, scope: { $all: requiredScopes } });
   return tokenData != null;
 };
 
-IAccessTokenSchema.methods.isExpired = function() {
+accessTokenSchema.methods.isExpired = function() {
   return this.expiredAt < new Date();
 };
 
-export const AccessToken = getOrCreateModel<IAccessTokenDocument, IAccessToken>('AccessToken', IAccessTokenSchema);
+export const AccessToken = getOrCreateModel<IAccessTokenDocument, IAccessToken>('AccessToken', accessTokenSchema);