<?php
/**
 * JWToken utilities.
 * @author Kiss Team
 * @category Plugin
 * @license MIT
 */
class JWToken {

	/* Décrypte une JWT Token avec la clé secrete fournie */
	public static function parse($encodedString,$key){
		$infos = explode('.', $encodedString);
	    if(count($infos)!=3) throw new Exception("JWT error : incorrect format", 401);

	    list($header64, $payloadb64, $signatureb64) = $infos;
	    $header = $header64;
	    $payload = $payloadb64;

		//header
	    $remainder = strlen($header) % 4;
	    if ($remainder) {
	        $padlen = 4 - $remainder;
	        $header .= str_repeat('=', $padlen);
	    }
	    $header = base64_decode(strtr($header, '-_', '+/'));
	    $header = json_decode($header,true);

		//payload
	    $remainder = strlen($payload) % 4;
	    if ($remainder) {
	        $padlen = 4 - $remainder;
	        $payload .= str_repeat('=', $padlen);
	    }
	    $payload = base64_decode(strtr($payload, '-_', '+/'));
	    $payload = json_decode($payload,true);

		//signature
	    $remainder = strlen($signatureb64) % 4;
	    if ($remainder) {
	        $padlen = 4 - $remainder;
	        $signatureb64 .= str_repeat('=', $padlen);
	    }
	    $signature = base64_decode(strtr($signatureb64, '-_', '+/'));
	    $hash = hash_hmac('SHA256', "$header64.$payloadb64", $key, true);
	    $len = min(mb_strlen($signature, '8bit'),mb_strlen($hash, '8bit')  );
	    $status = 0;
	    for ($i = 0; $i < $len; $i++) {
	        $status |= (ord($signature[$i]) ^ ord($hash[$i]));
	    }
	    $status |= (mb_strlen($signature, '8bit') ^ mb_strlen($hash, '8bit'));
	    $verify = ($status === 0);
	    if(!$verify) throw new Exception("JWT error : bad signature or encryption key", 401);

	    if($payload['exp']<time()) throw new Exception("JWT error : token is expired since ".date('d/m/Y H:i:s',$payload['exp']), 498);
	    return $payload;
	}

	//Créé un token crypté en HS256 à partir du payload / clé privée fournis
	public static function createFromJson($payload, $key) {
	    $header = json_encode(array('typ' => 'JWT', 'alg' => 'HS256'));
	    $payload = json_encode($payload);

	   	$segments = array();
	 	$segments[] = str_replace('=', '', strtr(base64_encode($header), '+/', '-_'));
	 	$segments[] = str_replace('=', '', strtr(base64_encode($payload), '+/', '-_'));
	    $signing_input = implode('.', $segments);
	    $signature =  hash_hmac('SHA256', $signing_input, $key, true);
	    $segments[] = str_replace('=', '', strtr(base64_encode($signature), '+/', '-_'));

	    return implode('.', $segments);
	}
}