manifest
Version:
Self-hosted Manifest LLM router with embedded server, SQLite database, and dashboard
252 lines • 11.6 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var MinimaxOauthService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isMinimaxRegion = exports.MINIMAX_DEFAULT_RESOURCE_URL = exports.MinimaxOauthService = void 0;
const common_1 = require("@nestjs/common");
const config_1 = require("@nestjs/config");
const crypto_1 = require("crypto");
const provider_service_1 = require("../routing-core/provider.service");
const model_discovery_service_1 = require("../../model-discovery/model-discovery.service");
const minimax_oauth_helpers_1 = require("./minimax-oauth-helpers");
const DEFAULT_CLIENT_ID = '78257093-7e40-4613-99e0-527b14b39113';
const SCOPE = 'group_id profile model.completion';
const USER_CODE_GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:user_code';
let MinimaxOauthService = MinimaxOauthService_1 = class MinimaxOauthService {
providerService;
configService;
discoveryService;
logger = new common_1.Logger(MinimaxOauthService_1.name);
pending = new Map();
clientId;
constructor(providerService, configService, discoveryService) {
this.providerService = providerService;
this.configService = configService;
this.discoveryService = discoveryService;
this.clientId = this.configService.get('MINIMAX_OAUTH_CLIENT_ID') ?? DEFAULT_CLIENT_ID;
}
async startAuthorization(agentId, userId, region = minimax_oauth_helpers_1.DEFAULT_REGION) {
this.cleanupExpired();
const verifier = (0, crypto_1.randomBytes)(32).toString('base64url');
const challenge = (0, crypto_1.createHash)('sha256').update(verifier).digest('base64url');
const flowId = (0, crypto_1.randomBytes)(16).toString('base64url');
const baseUrl = (0, minimax_oauth_helpers_1.getMinimaxBaseUrl)(region);
const resourceUrl = (0, minimax_oauth_helpers_1.buildMinimaxResourceUrl)(baseUrl);
const response = await fetch((0, minimax_oauth_helpers_1.buildMinimaxCodeUrl)(baseUrl), {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
'x-request-id': (0, crypto_1.randomUUID)(),
},
body: new URLSearchParams({
response_type: 'code',
client_id: this.clientId,
scope: SCOPE,
code_challenge: challenge,
code_challenge_method: 'S256',
state: flowId,
}),
});
if (!response.ok) {
const text = await response.text();
this.logger.error(`MiniMax OAuth code request failed: ${text}`);
throw new Error('Failed to start MiniMax OAuth');
}
const payload = (await response.json());
if (!payload.user_code || !payload.verification_uri || !payload.expired_in) {
throw new Error(payload.error ?? 'MiniMax OAuth returned an incomplete authorization payload.');
}
if (payload.state !== flowId)
throw new Error('MiniMax OAuth state mismatch');
const pollIntervalMs = (0, minimax_oauth_helpers_1.toPollIntervalMs)(payload.interval);
const expiresAt = (0, minimax_oauth_helpers_1.toAbsoluteExpiryTimestamp)(payload.expired_in);
this.pending.set(flowId, {
verifier,
userCode: payload.user_code,
agentId,
userId,
baseUrl,
resourceUrl,
expiresAt,
pollIntervalMs,
});
return {
flowId,
userCode: payload.user_code,
verificationUri: payload.verification_uri,
expiresAt,
pollIntervalMs,
};
}
async pollAuthorization(flowId, userId) {
this.cleanupExpired();
const pending = this.pending.get(flowId);
if (!pending) {
return { status: 'error', message: 'MiniMax login expired. Start again.' };
}
if (pending.userId !== userId) {
return { status: 'error', message: 'MiniMax login session does not match the current user.' };
}
if (Date.now() >= pending.expiresAt) {
this.pending.delete(flowId);
return { status: 'error', message: 'MiniMax login expired. Start again.' };
}
const response = await fetch((0, minimax_oauth_helpers_1.buildMinimaxTokenUrl)(pending.baseUrl), {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
},
body: new URLSearchParams({
grant_type: USER_CODE_GRANT_TYPE,
client_id: this.clientId,
user_code: pending.userCode,
code_verifier: pending.verifier,
}),
});
const text = await response.text();
const payload = this.parseTokenResponse(text);
if (!response.ok) {
const message = payload?.base_resp?.status_msg ?? text ?? 'MiniMax OAuth failed';
this.pending.delete(flowId);
return { status: 'error', message };
}
if (!payload) {
this.pending.delete(flowId);
return { status: 'error', message: 'MiniMax OAuth returned an invalid token response.' };
}
if (payload.status === 'error') {
this.pending.delete(flowId);
return { status: 'error', message: 'MiniMax OAuth failed. Please try again later.' };
}
if (payload.status !== 'success') {
return {
status: 'pending',
message: 'Waiting for MiniMax approval…',
pollIntervalMs: pending.pollIntervalMs,
};
}
if (!payload.access_token || !payload.refresh_token || !payload.expired_in) {
this.pending.delete(flowId);
return { status: 'error', message: 'MiniMax OAuth returned an incomplete token payload.' };
}
this.pending.delete(flowId);
const resourceUrl = (0, minimax_oauth_helpers_1.getMinimaxResourceUrl)(payload.resource_url) ?? pending.resourceUrl;
const blob = {
t: payload.access_token,
r: payload.refresh_token,
e: (0, minimax_oauth_helpers_1.toAbsoluteExpiryTimestamp)(payload.expired_in),
u: resourceUrl,
};
const { provider: savedProvider } = await this.providerService.upsertProvider(pending.agentId, pending.userId, 'minimax', JSON.stringify(blob), 'subscription');
try {
await this.discoveryService.discoverModels(savedProvider);
await this.providerService.recalculateTiers(pending.agentId);
}
catch (err) {
this.logger.warn(`Model discovery after MiniMax OAuth failed: ${err}`);
}
this.logger.log(`MiniMax OAuth token stored for agent=${pending.agentId}`);
return { status: 'success' };
}
async refreshAccessToken(refreshToken, resourceUrl) {
const baseUrl = (0, minimax_oauth_helpers_1.getMinimaxOauthBaseUrl)(resourceUrl);
const response = await fetch((0, minimax_oauth_helpers_1.buildMinimaxTokenUrl)(baseUrl), {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
},
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: this.clientId,
}),
});
if (!response.ok) {
const text = await response.text();
this.logger.error(`MiniMax token refresh failed: ${text}`);
throw new Error('Token refresh failed');
}
const payload = (await response.json());
if (!payload.access_token || !payload.expired_in) {
throw new Error('MiniMax token refresh returned an incomplete payload');
}
const nextResourceUrl = (0, minimax_oauth_helpers_1.getMinimaxResourceUrl)(payload.resource_url) ??
(0, minimax_oauth_helpers_1.getMinimaxResourceUrl)(resourceUrl) ??
(0, minimax_oauth_helpers_1.buildMinimaxResourceUrl)(baseUrl);
return {
t: payload.access_token,
r: payload.refresh_token || refreshToken,
e: (0, minimax_oauth_helpers_1.toAbsoluteExpiryTimestamp)(payload.expired_in),
...(nextResourceUrl ? { u: nextResourceUrl } : {}),
};
}
async unwrapToken(rawValue, agentId, userId) {
let blob;
try {
const parsed = JSON.parse(rawValue);
if (!(0, minimax_oauth_helpers_1.isOAuthTokenBlob)(parsed))
return null;
blob = parsed;
}
catch {
return null;
}
if (!blob.t || !blob.r || !blob.e)
return null;
if (Date.now() < blob.e - 60_000)
return blob;
try {
const refreshed = await this.refreshAccessToken(blob.r, blob.u);
await this.providerService.upsertProvider(agentId, userId, 'minimax', JSON.stringify(refreshed), 'subscription');
this.logger.log(`MiniMax OAuth token refreshed for agent=${agentId}`);
return refreshed;
}
catch (err) {
this.logger.error(`Failed to refresh MiniMax token: ${err}`);
return blob;
}
}
getPendingCount() {
return this.pending.size;
}
cleanupExpired() {
const now = Date.now();
for (const [flowId, pending] of this.pending.entries()) {
if (pending.expiresAt <= now)
this.pending.delete(flowId);
}
}
parseTokenResponse(text) {
if (!text)
return null;
try {
return JSON.parse(text);
}
catch {
return null;
}
}
};
exports.MinimaxOauthService = MinimaxOauthService;
exports.MinimaxOauthService = MinimaxOauthService = MinimaxOauthService_1 = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [provider_service_1.ProviderService,
config_1.ConfigService,
model_discovery_service_1.ModelDiscoveryService])
], MinimaxOauthService);
var minimax_oauth_helpers_2 = require("./minimax-oauth-helpers");
Object.defineProperty(exports, "MINIMAX_DEFAULT_RESOURCE_URL", { enumerable: true, get: function () { return minimax_oauth_helpers_2.DEFAULT_RESOURCE_URL; } });
var minimax_oauth_helpers_3 = require("./minimax-oauth-helpers");
Object.defineProperty(exports, "isMinimaxRegion", { enumerable: true, get: function () { return minimax_oauth_helpers_3.isMinimaxRegion; } });
//# sourceMappingURL=minimax-oauth.service.js.map