<commit_before>import jwt from 'koa-jwt'
import { hash, compare } from '../lib/bcrypt-promise'
import KoaRouter from 'koa-router'
let router = KoaRouter()

// list available rooms
router.get('/api/account/rooms', async (ctx, next) => {
  let rooms = await ctx.db.all('SELECT * FROM rooms WHERE status = ?', ['open'])
  return ctx.body = rooms
})

// login
router.post('/api/account/login', async (ctx, next) => {
  let {email, password, roomId} = ctx.request.body

  // check presence of all fields
  if (!email || !password || !roomId) {
    ctx.status = 422
    return ctx.body = 'Email, password, and room are required'
  }

  email = email.trim().toLowerCase()

  // get user
  let user = await ctx.db.get('SELECT * FROM users WHERE email = ?', [email])

  // validate password
  if (!user || !await compare(password, user.password)) {
    ctx.status = 401
    return
  }

  // validate roomId
  let room = await ctx.db.get('SELECT * FROM rooms WHERE id = ?', [roomId])

  if (!room || room.status !== 'open') {
    ctx.status = 401
    return ctx.body = 'Invalid Room'
  }

  delete user.password
  user.roomId = roomId

  // JWT for API calls is stored in httpOnly cookie
  let token = jwt.sign(user, 'shared-secret')
  ctx.cookies.set('id_token', token, {httpOnly: true})

  // client also persists this to localStorage
  ctx.body = user
})

// logout
router.get('/api/account/logout', async (ctx, next) => {
  ctx.cookies.set('id_token', '.', {httpOnly: true})
  ctx.status = 200
})<commit_msg>Return id as integer (from db) instead of string from POST input<commit_after>import jwt from 'koa-jwt'
import { hash, compare } from '../lib/bcrypt-promise'
import KoaRouter from 'koa-router'
let router = KoaRouter()

// list available rooms
router.get('/api/account/rooms', async (ctx, next) => {
  let rooms = await ctx.db.all('SELECT * FROM rooms WHERE status = ?', ['open'])
  return ctx.body = rooms
})

// login
router.post('/api/account/login', async (ctx, next) => {
  let {email, password, roomId} = ctx.request.body

  // check presence of all fields
  if (!email || !password || !roomId) {
    ctx.status = 422
    return ctx.body = 'Email, password, and room are required'
  }

  email = email.trim().toLowerCase()

  // get user
  let user = await ctx.db.get('SELECT * FROM users WHERE email = ?', [email])

  // validate password
  if (!user || !await compare(password, user.password)) {
    ctx.status = 401
    return
  }

  // validate roomId
  let room = await ctx.db.get('SELECT * FROM rooms WHERE id = ?', [roomId])

  if (!room || room.status !== 'open') {
    ctx.status = 401
    return ctx.body = 'Invalid Room'
  }

  delete user.password
  user.roomId = room.id

  // JWT for API calls is stored in httpOnly cookie
  let token = jwt.sign(user, 'shared-secret')
  ctx.cookies.set('id_token', token, {httpOnly: true})

  // client also persists this to localStorage
  ctx.body = user
})

// logout
router.get('/api/account/logout', async (ctx, next) => {
  ctx.cookies.set('id_token', '.', {httpOnly: true})
  ctx.status = 200
})
{'fraction_non_alphanumeric': 0.15608638743455497, 'fraction_numerical': 0.007853403141361256, 'mean_word_length': 3.228215767634855, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '7620825', 'n_tokens_mistral': 1030, 'n_tokens_neox': 990, 'n_words': 305}