]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/avatar/avatar.ts
Fix avatar url validation
[github/Chocobozzz/PeerTube.git] / server / models / avatar / avatar.ts
index 5d73e24fae4078b814d3e92ed6338b8156e36361..b4014459297fdffff140c7116b19cfcdd3b6fc5a 100644 (file)
@@ -1,12 +1,21 @@
 import { join } from 'path'
-import { AfterDestroy, AllowNull, Column, CreatedAt, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { AfterDestroy, AllowNull, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
 import { Avatar } from '../../../shared/models/avatars/avatar.model'
-import { CONFIG, STATIC_PATHS } from '../../initializers'
+import { LAZY_STATIC_PATHS } from '../../initializers/constants'
 import { logger } from '../../helpers/logger'
 import { remove } from 'fs-extra'
+import { CONFIG } from '../../initializers/config'
+import { throwIfNotValid } from '../utils'
+import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 
 @Table({
-  tableName: 'avatar'
+  tableName: 'avatar',
+  indexes: [
+    {
+      fields: [ 'filename' ],
+      unique: true
+    }
+  ]
 })
 export class AvatarModel extends Model<AvatarModel> {
 
@@ -14,6 +23,15 @@ export class AvatarModel extends Model<AvatarModel> {
   @Column
   filename: string
 
+  @AllowNull(true)
+  @Is('AvatarFileUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'fileUrl', true))
+  @Column
+  fileUrl: string
+
+  @AllowNull(false)
+  @Column
+  onDisk: boolean
+
   @CreatedAt
   createdAt: Date
 
@@ -23,19 +41,36 @@ export class AvatarModel extends Model<AvatarModel> {
   @AfterDestroy
   static removeFilesAndSendDelete (instance: AvatarModel) {
     logger.info('Removing avatar file %s.', instance.filename)
-    return instance.removeAvatar()
+
+    // Don't block the transaction
+    instance.removeAvatar()
+      .catch(err => logger.error('Cannot remove avatar file %s.', instance.filename, err))
+  }
+
+  static loadByName (filename: string) {
+    const query = {
+      where: {
+        filename
+      }
+    }
+
+    return AvatarModel.findOne(query)
   }
 
   toFormattedJSON (): Avatar {
     return {
-      path: this.getWebserverPath(),
+      path: this.getStaticPath(),
       createdAt: this.createdAt,
       updatedAt: this.updatedAt
     }
   }
 
-  getWebserverPath () {
-    return join(STATIC_PATHS.AVATARS, this.filename)
+  getStaticPath () {
+    return join(LAZY_STATIC_PATHS.AVATARS, this.filename)
+  }
+
+  getPath () {
+    return join(CONFIG.STORAGE.AVATARS_DIR, this.filename)
   }
 
   removeAvatar () {