/*
 * Copyright (c) 2014-2026 Bjoern Kimminich & the OWASP Juice Shop contributors.
 * SPDX-License-Identifier: MIT
 */

import { describe, it, before } from 'node:test'
import assert from 'node:assert/strict'
import request from 'supertest'
import type { Express } from 'express'
import config from 'config'
import { createTestApp } from './helpers/setup'
import { login } from './helpers/auth'
import * as datacache from '../../data/datacache'

let app: Express
let authHeader: { Cookie: string }

before(async () => {
  const result = await createTestApp()
  app = result.app
  const { token } = await login(app, { email: 'jim@juice-sh.op', password: 'ncc-1701' })
  authHeader = { Cookie: `token=${token}` }
}, { timeout: 60000 })

void describe('/profile', () => {
  void it('GET user profile is forbidden for unauthenticated user', async () => {
    const res = await request(app)
      .get('/profile')

    assert.equal(res.status, 500)
    assert.ok(res.headers['content-type']?.includes('text/html'))
    assert.ok(res.text.includes(`<h1>${config.get<string>('application.name')} (Express`))
    assert.ok(res.text.includes('Error: Blocked illegal activity'))
  })

  void it('GET user profile of authenticated user', async () => {
    const res = await request(app)
      .get('/profile')
      .set(authHeader)

    assert.equal(res.status, 200)
    assert.ok(res.headers['content-type']?.includes('text/html'))
    assert.ok(res.text.includes('id="email" type="email" name="email" value="jim@juice-sh.op"'))
  })

  void it('POST update username of authenticated user', async () => {
    const res = await request(app)
      .post('/profile')
      .set('Cookie', authHeader.Cookie)
      .field('username', 'Localhorst')
      .redirects(0)

    assert.equal(res.status, 302)
  })

  void it('POST update profile is forbidden for unauthenticated user', async () => {
    const res = await request(app)
      .post('/profile')
      .field('username', 'Anonhorst')

    assert.equal(res.status, 500)
    assert.ok(res.text.includes('Error: Blocked illegal activity'))
  })

  void it('GET user profile renders evaluated SSTI payload for username containing valid expression', async () => {
    await request(app)
      .post('/profile')
      .set('Cookie', authHeader.Cookie)
      .type('form')
      .send({ username: '#{7*7}' })
      .redirects(0)

    const res = await request(app)
      .get('/profile')
      .set(authHeader)

    assert.equal(res.status, 200)
    assert.ok(res.headers['content-type']?.includes('text/html'))
    assert.ok(res.text.includes('>49<'))
  })

  void it('GET user profile falls back gracefully when SSTI payload throws', async () => {
    await request(app)
      .post('/profile')
      .set('Cookie', authHeader.Cookie)
      .type('form')
      .send({ username: '#{not_a_defined_symbol}' })
      .redirects(0)

    const res = await request(app)
      .get('/profile')
      .set(authHeader)

    assert.equal(res.status, 200)
    assert.ok(res.headers['content-type']?.includes('text/html'))
    assert.ok(res.text.includes('not_a_defined_symbol'))
  })

  void it('should be solved when origin header matches configured CSRF URL', async () => {
    const csrfUrl = config.get<string>('challenges.overwriteUrlForCsrfChallenge')
    datacache.challenges.csrfChallenge.solved = false
    await request(app)
      .post('/profile')
      .set('Cookie', authHeader.Cookie)
      .set('Origin', csrfUrl)
      .send({ username: 'CSRF_Victim' })
      .expect(302)
    assert.equal(datacache.challenges.csrfChallenge.solved, true)
  })

  void it('should have the configured CSRF URL in the challenge description', async () => {
    const csrfUrl = config.get<string>('challenges.overwriteUrlForCsrfChallenge')
    assert.ok(datacache.challenges.csrfChallenge.description.includes(csrfUrl))
  })

  void it('should NOT be solved when origin header does NOT match configured CSRF URL', async () => {
    datacache.challenges.csrfChallenge.solved = false
    await request(app)
      .post('/profile')
      .set('Cookie', authHeader.Cookie)
      .set('Origin', 'http://attacker.com')
      .send({ username: 'No_CSRF' })
      .expect(302)
    assert.equal(datacache.challenges.csrfChallenge.solved, false)
  })
})
