<commit_before>
import Permission from '../classes/Permission'
import { User, db } from '../db'
import NicknameQuery from '../query/NicknameQuery'
import { CustomPresenter} from '../classes/Presenters'
import { NotFoundAPIError, ConflictAPIError, ForbiddenAPIError } from '../classes/APIError'

import NickServ from '../Anope/NickServ'
import HostServ from '../Anope/HostServ'
import API, {
  authenticated,
  GET,
  POST,
  PUT,
  DELETE,
  parameters,
} from '../classes/API'
import { websocket } from '../classes/WebSocket'

export default class Nicknames extends API {
  @GET('/nicknames/info/:nickname')
  @websocket('nicknames', 'info')
  @authenticated
  @parameters('nickname')
  async info (ctx) {
    let info = await NickServ.info(ctx.params.nickname)
    if (!info) {
      throw new NotFoundAPIError({ parameter: 'nickname' })
    }

    return Nicknames.presenter.render(info)
  }

  @POST('/nicknames')
  @websocket('nicknames', 'register')
  @authenticated
  async register (ctx) {
    if (Permission.isAdmin(ctx.state.user)) {
      throw new ForbiddenAPIError({})
    }

    ctx.data.nickname = ctx.data.nickname.toLowerCase()

    let { nicknames } = ctx.state.user.data.attributes
    if (nicknames.includes(ctx.data.nickname)) {
      throw new ConflictAPIError({ pointer: '/data/attributes/nickname' })
    }

    if (nicknames.length > 0) {
      await NickServ.group(ctx.data.nickname, nicknames[0], ctx.data.password)
    } else {
      await NickServ.register(ctx.data.nickname, ctx.data.password, ctx.state.user.data.attributes.email)
      await NickServ.confirm(ctx.data.nickname)
    }

    let updatedNicknames = await NickServ.list(ctx.data.nickname)

    await User.update({ updatedNicknames }, {
      where: { id: ctx.state.user.data.id }
    })

    await HostServ.update(ctx.state.user)
    return true
  }

  @PUT('/nicknames')
  @websocket('nicknames', 'connect')
  @authenticated
  async connect (ctx) {
    ctx.data.nickname = ctx.data.nickname.toLowerCase()
    let { nicknames } = ctx.state.user.data.attributes
    if (nicknames.includes(ctx.data.nickname)) {
      throw new ConflictAPIError({ pointer: '/data/attributes/nickname' })
    }

    await NickServ.identify(ctx.data.nickname, ctx.data.password)
    if (nicknames.length > 0) {
      await NickServ.group(ctx.data.nickname, nicknames[0], ctx.data.password)
    }

    let updatedNicknames = await NickServ.list(ctx.data.nickname)

    await User.update({ nicknames: updatedNicknames }, {
      where: { id: ctx.state.user.data.id }
    })


    await HostServ.update(ctx.state.user)
    return true
  }

  @GET('/nicknames/:nickname')
  @websocket('nicknames', 'search')
  @authenticated
  @parameters('nickname')
  async search (ctx) {
    let result = await User.scope('public').findAndCountAll(new NicknameQuery(ctx.params, ctx).toSequelize)
    return Nicknames.presenter.render(result)
  }

  @DELETE('/nicknames/:nickname')
  @websocket('nicknames', 'delete')
  @authenticated
  @parameters('nickname')
  async delete (ctx) {
    ctx.params.nickname = ctx.params.nickname.toLowerCase()
    if (ctx.state.user.data.attributes.nicknames.includes(ctx.params.nickname) ||
      Permission.require(['nickname.delete'], ctx.state.user, ctx.state.scope)) {
      await NickServ.drop(ctx.params.nickname)

      let nicknames = await NickServ.list(ctx.state.user.data.attributes.nicknames[0])

      await User.update({
        nicknames: db.cast(nicknames, 'citext[]')
      }, {
        where: {
          id: ctx.state.user.data.id
        }
      })<commit_msg>Add endpoint for refreshing a user's nickname list from nickserv<commit_after>
import Permission from '../classes/Permission'
import { User, db } from '../db'
import NicknameQuery from '../query/NicknameQuery'
import { CustomPresenter} from '../classes/Presenters'
import { NotFoundAPIError, ConflictAPIError, ForbiddenAPIError } from '../classes/APIError'

import NickServ from '../Anope/NickServ'
import HostServ from '../Anope/HostServ'
import API, {
  authenticated,
  GET,
  POST,
  PUT,
  DELETE,
  parameters,
} from '../classes/API'
import { websocket } from '../classes/WebSocket'

export default class Nicknames extends API {
  @GET('/nicknames/info/:nickname')
  @websocket('nicknames', 'info')
  @authenticated
  @parameters('nickname')
  async info (ctx) {
    let info = await NickServ.info(ctx.params.nickname)
    if (!info) {
      throw new NotFoundAPIError({ parameter: 'nickname' })
    }

    return Nicknames.presenter.render(info)
  }

  @POST('/nicknames')
  @websocket('nicknames', 'register')
  @authenticated
  async register (ctx) {
    if (Permission.isAdmin(ctx.state.user)) {
      throw new ForbiddenAPIError({})
    }

    ctx.data.nickname = ctx.data.nickname.toLowerCase()

    let { nicknames } = ctx.state.user.data.attributes
    if (nicknames.includes(ctx.data.nickname)) {
      throw new ConflictAPIError({ pointer: '/data/attributes/nickname' })
    }

    if (nicknames.length > 0) {
      await NickServ.group(ctx.data.nickname, nicknames[0], ctx.data.password)
    } else {
      await NickServ.register(ctx.data.nickname, ctx.data.password, ctx.state.user.data.attributes.email)
      await NickServ.confirm(ctx.data.nickname)
    }

    let updatedNicknames = await NickServ.list(ctx.data.nickname)

    await User.update({ updatedNicknames }, {
      where: { id: ctx.state.user.data.id }
    })

    await HostServ.update(ctx.state.user)
    return true
  }

  @PUT('/nicknames')
  @websocket('nicknames', 'connect')
  @authenticated
  async connect (ctx) {
    ctx.data.nickname = ctx.data.nickname.toLowerCase()
    let { nicknames } = ctx.state.user.data.attributes
    if (nicknames.includes(ctx.data.nickname)) {
      throw new ConflictAPIError({ pointer: '/data/attributes/nickname' })
    }

    await NickServ.identify(ctx.data.nickname, ctx.data.password)
    if (nicknames.length > 0) {
      await NickServ.group(ctx.data.nickname, nicknames[0], ctx.data.password)
    }

    let updatedNicknames = await NickServ.list(ctx.data.nickname)

    await User.update({ nicknames: updatedNicknames }, {
      where: { id: ctx.state.user.data.id }
    })


    await HostServ.update(ctx.state.user)
    return true
  }

  @GET('/nicknames/refresh')
  @websocket('nicknames', 'refresh')
  @authenticated
  async refresh (ctx) {
    let updatedNicknames = await NickServ.list(ctx.data.nickname)

    await User.update({ nicknames: updatedNicknames }, {
      where: { id: ctx.state.user.data.id }
    })
    await HostServ.update(ctx.state.user)
    return true
  }

  @GET('/nicknames/:nickname')
  @websocket('nicknames', 'search')
  @authenticated
  @parameters('nickname')
  async search (ctx) {
    let result = await User.scope('public').findAndCountAll(new NicknameQuery(ctx.params, ctx).toSequelize)
    return Nicknames.presenter.render(result)
  }

  @DELETE('/nicknames/:nickname')
  @websocket('nicknames', 'delete')
  @authenticated
  @parameters('nickname')
  async delete (ctx) {
    ctx.params.nickname = ctx.params.nickname.toLowerCase()
    if (ctx.state.user.data.attributes.nicknames.includes(ctx.params.nickname) ||
      Permission.require(['nickname.delete'], ctx.state.user, ctx.state.scope)) {
      await NickServ.drop(ctx.params.nickname)

      let nicknames = await NickServ.list(ctx.state.user.data.attributes.nicknames[0])

      await User.update({
        nicknames: db.cast(nicknames, 'citext[]')
      }, {
        where: {
          id: ctx.state.user.data.id
        }
      })
{'fraction_non_alphanumeric': 0.14189009822139634, 'fraction_numerical': 0.0013273161667109105, 'mean_word_length': 3.4141769185705915, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '203439', 'n_tokens_mistral': 2466, 'n_tokens_neox': 2409, 'n_words': 459}