Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagetypescript
import * as jsonwebtoken from 'jsonwebtoken';
import fs from 'fs';
import {JWTPrivateKey} from './JWTPrivateKey';
import axios from 'axios';

// Sample usage:
// await new MicromateRequest().callMicromatePublicApi();
export class MicromateRequest {

    public async callMicromatePublicApi(): Promise<void> {
        const token = await this.getOAuthToken();
        const data = await axios.get('http://bot.micromate.ai/api/public/organization/{organizationId}/learningPackage/{learningPackageId}/questions', {
            headers: {Authorization: `Bearer ${token}`}
        });

        console.log('Data retrieved from micromate public api: ', data.data);
    }

    private createSignedJWT(): string {
        // Read the private key
        const rawPrivateKey = fs.readFileSync('./privateKey.json', 'utf8');
        const privateKey = JSON.parse(rawPrivateKey) as JWTPrivateKey;

        // Valid from now minus 10 seconds
        const validFrom: number = Math.floor(Date.now() / 1000) - 10;

        // Expiration 1 hour after now
        const expiration: number = Math.floor(Date.now() / 1000) + (60 * 60);

        // Create a JWT token
        const jwtToSign = {
            iss: privateKey.userId,
            sub: privateKey.userId,
            aud: 'https://login.micromate.ai',
            iat: validFrom,
            exp: expiration
        };

        // Sign and return the token
        return jsonwebtoken.sign(jwtToSign, privateKey.key, {algorithm: 'RS256', keyid: privateKey.keyId});
    }

    private async getOAuthToken(): Promise<string> {
        // Create signed token
        const token = this.createSignedJWT();

        // Request to token endpoint to get an access token
        // which then can be used to access the micromate public api
        const data = await axios.post<TokenResponse>('https://login.micromate.ai/oauth/v2/token', {}, {
            params: {
                'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                'scope': 'openid profile email urn:zitadel:iam:org:project:id:69234237810729019122147021183311927:aud urn:zitadel:iam:org:projects:roles',
                'assertion': token
            },
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        });

        // Return access token
        return data.data.access_token;
    }
}

export interface JWTPrivateKey {
    type: string,
    keyId: string,
    key: string,
    userId: string
}

export interface TokenResponse {
    token_type: string,
    access_token: string,
    expires_in: number
}

...

Code Block
languagephp
<?php
// Read private key from file
$privateKey = file_get_contents("privateKey.json");
$privateKeyData = json_decode($privateKey);

$jwtHeader = base64url_encode(json_encode(array(
    "alg" => "RS256",
    "typ" => "JWT",
    "kid" => $privateKeyData->{'keyId'}
)));

$now = time();
$jwtClaim = base64url_encode(json_encode(array(
    "iss" => $privateKeyData->{'userId'},
    "sub" => $privateKeyData->{'userId'},
    "aud" => "https://login.micromate.ai",
    "iat" => $now,
    "exp" => $now + 3600
)));

// Create the data strign we want to have a signature for
$dataToSign = $jwtHeader . "." . $jwtClaim;

// Create the signature for our data
$signature = '';
openssl_sign($dataToSign, $signature, $privateKeyData->{'key'}, 'sha256');
$jwtSign = base64url_encode($signature);

// Concat our data with the created signature --> This is the asseration we can use to authenticate
$jwtAssertion = $dataToSign . "." . $jwtSign;

// Build the content for the OAuth-Token-Request
$content = http_build_query(array(
    "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "scope" => "openid profile email urn:zitadel:iam:org:project:id:120959397714256297122147021183311927:aud urn:zitadel:iam:org:projects:roles",
    "assertion" => $jwtAssertion
), '', '&');


// Request OAuth-Token
$context = stream_context_create(array(
    'http' => array(
        'method' => 'POST',
        'header' => 'Content-Type: application/x-www-form-urlencoded',
        'ignore_errors' => true,
        'content' => $content
    )
));

$result = file_get_contents('https://login.micromate.ai/oauth/v2/token', false, $context);

// Print the OAuth-Token in the format: 
// {"access_token":"<Token>","token_type":"Bearer","expires_in":43199}
echo $result;


function base64url_encode($data)
{
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}