reiji-h 1 год назад
Родитель
Сommit
4f927ba28e
1 измененных файлов с 27 добавлено и 32 удалено
  1. 27 32
      apps/app/src/server/models/access-token.ts

+ 27 - 32
apps/app/src/server/models/access-token.ts

@@ -1,5 +1,6 @@
 import crypto from 'crypto';
 
+import type { Ref, IUser, IUserHasId } from '@growi/core/dist/interfaces';
 import type { Document, Model, Types } from 'mongoose';
 import { Schema } from 'mongoose';
 import mongoosePaginate from 'mongoose-paginate-v2';
@@ -9,41 +10,35 @@ 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<IUser>,
   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
 }
 
 export interface IAccessTokenModel extends Model<IAccessTokenDocument> {
-  generateToken: (userId: Types.ObjectId, expiredAt: Date, scope: string[], description?: string,) => Promise<string>
+  generateToken: (user: IUserHasId, expiredAt: Date, scope: string[], description?: string,) => Promise<string>
   deleteToken: (token: string) => Promise<void>
   deleteTokenById: (tokenId: Types.ObjectId) => Promise<void>
-  deleteAllTokensByUserId: (userId: Types.ObjectId) => Promise<void>
+  deleteAllTokensByUserId: (user: IUserHasId) => Promise<void>
   deleteExpiredToken: () => Promise<void>
-  findUserIdByToken: (token: string) => Promise<IAccessTokenDocument>
-  findTokenByUserId: (userId: Types.ObjectId) => Promise<IAccessTokenDocument[]>
+  findUserByToken: (token: string) => Promise<IUserHasId>
+  findTokenByUser: (user: IUserHasId) => 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(user: IUserHasId, 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: user._id, 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(user: IUserHasId) {
+  return this.deleteMany({ user: user._id });
 };
 
-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.findUserByToken = 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 } }).populate('user');
 };
 
-IAccessTokenSchema.statics.findTokenByUserId = async function(userId: Types.ObjectId) {
+accessTokenSchema.statics.findTokenByUser = async function(user: IUserHasId) {
   const now = new Date();
-  return this.find({ userId, expiredAt: { $gt: now } }).select('_id expiredAt scope description');
+  return this.find({ user: user._id, 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);