ai-auth
Version:
Complete Auth-Agent SDK - Agent authentication for AI developers + OAuth client integration for website developers
85 lines • 2.55 kB
JavaScript
;
/**
* Utility functions for Auth-Agent SDK
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.generatePKCEAsync = generatePKCEAsync;
exports.generateState = generateState;
exports.parseJWT = parseJWT;
exports.isTokenExpired = isTokenExpired;
exports.getTimeUntilExpiry = getTimeUntilExpiry;
exports.sleep = sleep;
const node_crypto_1 = require("node:crypto");
// Use Node.js crypto in browser environments
const crypto = globalThis.crypto || node_crypto_1.webcrypto;
/**
* Base64 URL encode a buffer
*/
function base64URLEncode(buffer) {
// Convert to base64
const base64 = Buffer.from(buffer).toString('base64');
// Make URL-safe
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
/**
* Generate PKCE code verifier and challenge with SHA-256
* OAuth 2.1 compliant
*/
async function generatePKCEAsync() {
// Generate code verifier (random string)
const array = new Uint8Array(32);
crypto.getRandomValues(array);
const codeVerifier = base64URLEncode(array);
// Generate code challenge (SHA-256 hash of verifier)
const encoder = new TextEncoder();
const data = encoder.encode(codeVerifier);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = new Uint8Array(hashBuffer);
const codeChallenge = base64URLEncode(hashArray);
return { codeVerifier, codeChallenge };
}
/**
* Generate a random state parameter for CSRF protection
*/
function generateState() {
const array = new Uint8Array(16);
crypto.getRandomValues(array);
return base64URLEncode(array);
}
/**
* Parse JWT token (without verification)
* Only use for reading claims, not for security validation
*/
function parseJWT(token) {
try {
const parts = token.split('.');
if (parts.length !== 3) {
throw new Error('Invalid JWT format');
}
const payload = parts[1];
const decoded = Buffer.from(payload.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf-8');
return JSON.parse(decoded);
}
catch {
return null;
}
}
/**
* Check if token is expired
*/
function isTokenExpired(expiresAt) {
return expiresAt <= Date.now();
}
/**
* Get time until token expires (in milliseconds)
*/
function getTimeUntilExpiry(expiresAt) {
return Math.max(0, expiresAt - Date.now());
}
/**
* Sleep for a specified duration
*/
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
//# sourceMappingURL=utils.js.map