LibreChat/api/strategies/jwtStrategy.js
Danny Avila aa35cd42b1
📬 feat: Add Durable Agent Trigger Delivery (#14925)
* feat: wire trusted agent trigger dispatch

* feat: add durable agent trigger delivery

* fix: annotate trigger envelope byte limit

* test: isolate trigger startup in server specs

* fix: fence trigger delivery during account deletion

* test: isolate trigger service in user controller specs

* fix: close trigger deletion admission race

* fix: harden account deletion fences

* fix: close durable trigger review gaps

* fix: require offline stale-fence recovery

* fix: type trigger lane sequence ids

* fix: fence admin user deletion triggers

* fix: make trigger deletion recovery durable

* fix: harden offline user deletion

* fix: serialize trigger lane publication

* style: sort trigger delivery imports

* fix: recover orphaned trigger publications

* fix: preserve trigger recovery ordering

* fix: fence trigger publication during purge

* fix: defer remote trigger deletion fences

* fix: close durable delivery cleanup races

* fix: drain CLI generation owners before deletion
2026-08-17 09:25:08 -04:00

69 lines
2.4 KiB
JavaScript

const { AGENT_TRIGGER_SCOPE } = require('@librechat/api');
const { logger, runAsSystem } = require('@librechat/data-schemas');
const { SystemRoles } = require('librechat-data-provider');
const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt');
const { getUserById, updateUser } = require('~/models');
const AGENT_TRIGGER_ADMISSION_PATHS = ['/api/agents/chat/agents', '/api/agents/chat/steer/deliver'];
/** A trigger-scoped bearer is deliberately useless outside the two internal
* admission routes that the execution host calls. */
function isAgentTriggerAdmissionRequest(req) {
if (req?.method !== 'POST' || req?.headers?.['x-lc-agent-trigger'] !== '1') {
return false;
}
try {
const pathname = new URL(req.originalUrl ?? req.url ?? '', 'http://localhost').pathname;
return AGENT_TRIGGER_ADMISSION_PATHS.some((path) => pathname.endsWith(path));
} catch {
return false;
}
}
// JWT strategy
const jwtLogin = () =>
new JwtStrategy(
{
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET,
passReqToCallback: true,
},
async (req, payload, done) => {
try {
if (payload?.scope === AGENT_TRIGGER_SCOPE && !isAgentTriggerAdmissionRequest(req)) {
done(null, false, { message: 'Agent trigger token is not valid for this endpoint' });
return;
}
const user = await runAsSystem(() =>
getUserById(
payload?.id,
'-password -__v -totpSecret -backupCodes +agentTriggerDeletionStartedAt',
),
);
if (user?.agentTriggerDeletionStartedAt != null) {
done(null, false, {
message: 'Account deletion is in progress',
code: 'ACCOUNT_DELETION_IN_PROGRESS',
});
return;
}
if (user) {
user.id = user._id.toString();
/** Absent on the full doc means local user; null skips getUserPrincipals' fallback lookup */
user.idOnTheSource ??= null;
if (!user.role) {
user.role = SystemRoles.USER;
await runAsSystem(() => updateUser(user.id, { role: user.role }));
}
done(null, user);
} else {
logger.warn('[jwtLogin] JwtStrategy => no user found: ' + payload?.id);
done(null, false);
}
} catch (err) {
done(err, false);
}
},
);
module.exports = jwtLogin;