<?php

/*
 * 	This controller handles the following request:
 *
 *  update token (login)
 *
 * 		Method: POST
 * 		GET Parameters:
 * 			service=authenticate
 * 		POST Parameters:
 * 			username=username
 * 			token=token
 * 			new=new
 * 		Response:
 * 			200 Ok
 * 			JSON
 * 				{
 * 					'authenticated': 'true',
 * 					'username': '<username>'
 * 				}
 *
 * 			401 Unauthorized
 * 			JSON
 * 				{
 * 					'error': {
 * 						'code': <nr>
 * 						'message: '<error message>'
 * 					}
 * 				}
 *
 */

require_once BASE_PATH . 'server/includes/core/class.response.php';
require_once BASE_PATH . 'server/includes/core/class.webappauthentication.php';

/**
 * Decode an JWT access token which contains of a header, payload and
 * verify signature separated by a dot.
 *
 * @param string $accessToken the accessToken to extract the user entryid from
 *
 * @return string empty string when entryid is not found
 */
function extractUserEntryId($accessToken) {
	$parts = explode(".", $accessToken);
	if (count($parts) !== 3) {
		return '';
	}

	$data = base64_decode($parts[1]);
	if (!$data) {
		return '';
	}

	$json = json_decode($data, true);
	if (!$json) {
		return '';
	}

	if (!isset($json['kc.identity']) || !isset($json['kc.identity']['kc.i.id'])) {
		return '';
	}

	return $json['kc.identity']['kc.i.id'];
}

// This request only works when POSTed
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
	Response::wrongMethod();
}

// Add CORS headers if necessary
Response::addCorsHeaders();

$new = isset($_POST['new']);

if (isset($_POST['token'])) {
	$_POST['username'] = extractUserEntryid($_POST['token']);
	WebAppAuthentication::authenticateWithToken($new);
}

if (WebAppAuthentication::getErrorCode() !== NOERROR) {
	// If we have an error, we will communicate it in our response
	$response['error'] = [
		'code' => WebAppAuthentication::getErrorCode(),
		'hcode' => get_mapi_error_name(WebAppAuthentication::getErrorCode()),
		'message' => WebAppAuthentication::getErrorMessage(),
	];
}
else {
	// We successfully logged in, so we can communicate this in our response
	$response = [
		'authenticated' => WebAppAuthentication::isAuthenticated(),
		'user' => WebAppAuthentication::getUserName(),
	];
}

// We will send a 401 header when the user is not authenticated
// We also send it when there was an error when we tried to log in. This error
// could be that another user is already logged in. (Not sure if 401 is logical then)
if (!WebAppAuthentication::isAuthenticated() || WebAppAuthentication::getErrorCode() !== NOERROR) {
	header('HTTP/1.1 401 Unauthorized');
}

// Send the response and stop the script
echo json_encode($response);

exit;
