<commit_before>import {
  AfterDestroy,
  AfterUpdate,
  AllowNull,
  BelongsTo,
  Column,
  CreatedAt,
  ForeignKey,
  Model,
  Scopes,
  Table,
  UpdatedAt
} from 'sequelize-typescript'
import { logger } from '../../helpers/logger'
import { UserModel } from '../account/user'
import { OAuthClientModel } from './oauth-client'
import { Transaction } from 'sequelize'
import { AccountModel } from '../account/account'
import { ActorModel } from '../activitypub/actor'
import { clearCacheByToken } from '../../lib/oauth-model'
import * as Bluebird from 'bluebird'
import { MOAuthTokenUser } from '@server/typings/models/oauth/oauth-token'

export type OAuthTokenInfo = {
  refreshToken: string
  refreshTokenExpiresAt: Date
  client: {
    id: number
  }
  user: {
    id: number
  }
  token: MOAuthTokenUser
}

enum ScopeNames {
  WITH_USER = 'WITH_USER'
}

@Scopes(() => ({
  [ScopeNames.WITH_USER]: {
    include: [
      {
        model: UserModel.unscoped(),
        required: true,
        include: [
          {
            attributes: [ 'id' ],
            model: AccountModel.unscoped(),
            required: true,
            include: [
              {
                attributes: [ 'id', 'url' ],
                model: ActorModel.unscoped(),
                required: true
              }
            ]
          }
        ]
      }
    ]
  }
}))
@Table({
  tableName: 'oAuthToken',
  indexes: [
    {
      fields: [ 'refreshToken' ],
      unique: true
    },
    {
      fields: [ 'accessToken' ],
      unique: true
    },
    {
      fields: [ 'userId' ]
    },
    {
      fields: [ 'oAuthClientId' ]
    }
  ]
})
export class OAuthTokenModel extends Model<OAuthTokenModel> {

  @AllowNull(false)
  @Column
  accessToken: string

  @AllowNull(false)
  @Column
  accessTokenExpiresAt: Date

  @AllowNull(false)
  @Column
  refreshToken: string

  @AllowNull(false)
  @Column
  refreshTokenExpiresAt: Date

  @Column
  authName: string

  @CreatedAt
  createdAt: Date

  @UpdatedAt
  updatedAt: Date

  @ForeignKey(() => UserModel)
  @Column
  userId: number

  @BelongsTo(() => UserModel, {
    foreignKey: {
      allowNull: false
    },
    onDelete: 'cascade'
  })
  User: UserModel

  @ForeignKey(() => OAuthClientModel)
  @Column
  oAuthClientId: number

  @BelongsTo(() => OAuthClientModel, {
    foreignKey: {
      allowNull: false
    },
    onDelete: 'cascade'
  })
  OAuthClients: OAuthClientModel[]

  @AfterUpdate
  @AfterDestroy
  static removeTokenCache (token: OAuthTokenModel) {
    return clearCacheByToken(token.accessToken)
  }

  static loadByRefreshToken (refreshToken: string) {
    const query = {
      where: { refreshToken }
    }

    return OAuthTokenModel.findOne(query)
  }

  static getByRefreshTokenAndPopulateClient (refreshToken: string) {
    const query = {
      where: {
        refreshToken
      },
      include: [ OAuthClientModel ]
    }

    return OAuthTokenModel.scope(ScopeNames.WITH_USER)
                          .findOne(query)
                          .then(token => {
                            if (!token) return null

                            return {
                              refreshToken: token.refreshToken,
                              refreshTokenExpiresAt: token.refreshTokenExpiresAt,
                              client: {
                                id: token.oAuthClientId
                              },
                              user: {
                                id: token.userId
                              },
                              token
                            } as OAuthTokenInfo
                          })<commit_msg>Fix refresh token<commit_after>import {
  AfterDestroy,
  AfterUpdate,
  AllowNull,
  BelongsTo,
  Column,
  CreatedAt,
  ForeignKey,
  Model,
  Scopes,
  Table,
  UpdatedAt
} from 'sequelize-typescript'
import { logger } from '../../helpers/logger'
import { UserModel } from '../account/user'
import { OAuthClientModel } from './oauth-client'
import { Transaction } from 'sequelize'
import { AccountModel } from '../account/account'
import { ActorModel } from '../activitypub/actor'
import { clearCacheByToken } from '../../lib/oauth-model'
import * as Bluebird from 'bluebird'
import { MOAuthTokenUser } from '@server/typings/models/oauth/oauth-token'

export type OAuthTokenInfo = {
  refreshToken: string
  refreshTokenExpiresAt: Date
  client: {
    id: number
  }
  user: {
    id: number
  }
  token: MOAuthTokenUser
}

enum ScopeNames {
  WITH_USER = 'WITH_USER'
}

@Scopes(() => ({
  [ScopeNames.WITH_USER]: {
    include: [
      {
        model: UserModel.unscoped(),
        required: true,
        include: [
          {
            attributes: [ 'id' ],
            model: AccountModel.unscoped(),
            required: true,
            include: [
              {
                attributes: [ 'id', 'url' ],
                model: ActorModel.unscoped(),
                required: true
              }
            ]
          }
        ]
      }
    ]
  }
}))
@Table({
  tableName: 'oAuthToken',
  indexes: [
    {
      fields: [ 'refreshToken' ],
      unique: true
    },
    {
      fields: [ 'accessToken' ],
      unique: true
    },
    {
      fields: [ 'userId' ]
    },
    {
      fields: [ 'oAuthClientId' ]
    }
  ]
})
export class OAuthTokenModel extends Model<OAuthTokenModel> {

  @AllowNull(false)
  @Column
  accessToken: string

  @AllowNull(false)
  @Column
  accessTokenExpiresAt: Date

  @AllowNull(false)
  @Column
  refreshToken: string

  @AllowNull(false)
  @Column
  refreshTokenExpiresAt: Date

  @Column
  authName: string

  @CreatedAt
  createdAt: Date

  @UpdatedAt
  updatedAt: Date

  @ForeignKey(() => UserModel)
  @Column
  userId: number

  @BelongsTo(() => UserModel, {
    foreignKey: {
      allowNull: false
    },
    onDelete: 'cascade'
  })
  User: UserModel

  @ForeignKey(() => OAuthClientModel)
  @Column
  oAuthClientId: number

  @BelongsTo(() => OAuthClientModel, {
    foreignKey: {
      allowNull: false
    },
    onDelete: 'cascade'
  })
  OAuthClients: OAuthClientModel[]

  @AfterUpdate
  @AfterDestroy
  static removeTokenCache (token: OAuthTokenModel) {
    return clearCacheByToken(token.accessToken)
  }

  static loadByRefreshToken (refreshToken: string) {
    const query = {
      where: { refreshToken }
    }

    return OAuthTokenModel.findOne(query)
  }

  static getByRefreshTokenAndPopulateClient (refreshToken: string) {
    const query = {
      where: {
        refreshToken
      },
      include: [ OAuthClientModel ]
    }

    return OAuthTokenModel.scope(ScopeNames.WITH_USER)
                          .findOne(query)
                          .then(token => {
                            if (!token) return null

                            return {
                              refreshToken: token.refreshToken,
                              refreshTokenExpiresAt: token.refreshTokenExpiresAt,
                              client: {
                                id: token.oAuthClientId
                              },
                              user: token.User,
                              token
                            } as OAuthTokenInfo
                          })
{'fraction_non_alphanumeric': 0.10580912863070539, 'fraction_numerical': 0.0, 'mean_word_length': 1.781153846153846, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7467604', 'n_tokens_mistral': 2151, 'n_tokens_neox': 2114, 'n_words': 433}