Remove legacy files from the abandoned hand-built-image attempt (approved cleanup)
This commit is contained in:
1 parent
f40680f5a7
commit
5169915641
4 files changed
-79
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 6.6 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<image href="data:image/png;base64,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 truncated
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 6.6 KiB |
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* Key broker sync — automatically provision a member's gateway key at SSO login.
|
||||
*
|
||||
* Inference Cooperative patch (MIT, same as LibreChat). When KEY_BROKER_URL is
|
||||
* set, an OpenID (Cloudron SSO) login fetches-or-creates the member's chat key
|
||||
* via the member portal's broker and stores it as the user's LibreChat key for
|
||||
* the configured endpoint — so members never paste a key and all usage bills
|
||||
* to their own LiteLLM team/budget.
|
||||
*
|
||||
* Env:
|
||||
* KEY_BROKER_URL e.g. https://portal.inference.coop
|
||||
* KEY_BROKER_SECRET the portal's BROKER_SECRET (x-broker-secret header)
|
||||
* KEY_BROKER_KEY_NAME portal-side key name, default "chat"
|
||||
* KEY_BROKER_ENDPOINT LibreChat endpoint (user-key) name, default "Inference Co-op"
|
||||
*
|
||||
* Semantics: create-on-first-login. If the member already has a portal-side
|
||||
* "chat" key but LibreChat lost its stored copy, we deliberately do NOT rotate
|
||||
* (rotation would silently break the member's own API scripts); they can
|
||||
* rotate from the dashboard and log in again.
|
||||
*/
|
||||
const { updateUserKey, getUserKeyExpiry } = require('~/models');
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
|
||||
async function syncBrokerUserKey(user) {
|
||||
const base = process.env.KEY_BROKER_URL;
|
||||
const secret = process.env.KEY_BROKER_SECRET;
|
||||
const userId = user?._id?.toString?.() || user?.id;
|
||||
if (!base || !secret || !userId || !user?.email) return;
|
||||
const keyName = process.env.KEY_BROKER_KEY_NAME || 'chat';
|
||||
const endpointName = process.env.KEY_BROKER_ENDPOINT || 'Inference Co-op';
|
||||
const headers = {
|
||||
'x-broker-secret': secret,
|
||||
'x-member-email': user.email,
|
||||
};
|
||||
|
||||
// Does the member already have a portal-side chat key?
|
||||
const listRes = await fetch(`${base}/broker/keys`, { headers });
|
||||
if (!listRes.ok) throw new Error(`broker list ${listRes.status}`);
|
||||
const list = await listRes.json();
|
||||
const exists = (list.keys || []).some((k) => k.name === keyName);
|
||||
|
||||
if (!exists) {
|
||||
const createRes = await fetch(`${base}/broker/keys`, {
|
||||
method: 'POST',
|
||||
headers: { ...headers, 'content-type': 'application/json' },
|
||||
body: JSON.stringify({ name: keyName }),
|
||||
});
|
||||
if (!createRes.ok) throw new Error(`broker create ${createRes.status}`);
|
||||
const created = await createRes.json();
|
||||
if (!created.sk_token) throw new Error('broker returned no sk_token');
|
||||
// Store the key in LibreChat (JSON string as required by LibreChat storage)
|
||||
await updateUserKey({
|
||||
userId: userId,
|
||||
name: endpointName,
|
||||
value: JSON.stringify({ apiKey: created.sk_token }),
|
||||
expiresAt: null,
|
||||
});
|
||||
logger.info(`[KeyBroker] provisioned "${keyName}" key for ${user.email} (endpoint: ${endpointName})`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Portal-side key exists — check whether LibreChat still holds a stored copy.
|
||||
try {
|
||||
const stored = await getUserKeyExpiry({ userId: user.id, name: endpointName });
|
||||
if (!stored) {
|
||||
logger.warn(
|
||||
`[KeyBroker] ${user.email} has a portal "${keyName}" key but no stored copy for endpoint "${endpointName}". ` +
|
||||
'Rotate the key on the dashboard and log in again (manual rotation avoids breaking their API scripts).',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warn(`[KeyBroker] stored-key check failed for ${user.email}: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { syncBrokerUserKey };
|
||||
Reference in new issue
Block a user