mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-10-20 17:13:44 +00:00
🔐 feat: Add Signed CloudFront File Downloads (#12970)
* feat: add signed CloudFront downloads * fix: preserve local IdP avatar paths * fix: address signed download review findings * fix: harden CloudFront cookie scope validation * fix: preserve URL save API compatibility * fix: store CDN SSO avatars under shared prefix * fix: Harden CloudFront tenant file access * fix: Preserve CloudFront download compatibility * fix: Address CloudFront review follow-ups * fix: Preserve file URL fallback user paths * fix: Address download review hardening * fix: Use file owner for S3 RAG cleanup * fix: Address final download review nits * fix: Clear stale avatar CloudFront cookies * fix: Align download filename helpers with dev * fix: Address final CloudFront review follow-ups * fix: Stream S3 URL uploads * fix: Set S3 stream upload length * fix: Preserve download metadata filepath * fix: Avoid remote content length for stream uploads * fix: Use bounded multipart URL uploads * fix: Harden S3 filename boundaries
This commit is contained in:
parent
4bd5630651
commit
9c81792d25
63 changed files with 3080 additions and 289 deletions
|
|
@ -16,7 +16,7 @@ const loginController = async (req, res) => {
|
|||
const { password: _p, totpSecret: _t, __v, ...user } = req.user;
|
||||
user.id = user._id.toString();
|
||||
|
||||
const token = await setAuthTokens(req.user._id, res);
|
||||
const token = await setAuthTokens(req.user._id, res, null, req);
|
||||
|
||||
return res.status(200).send({ token, user });
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,10 @@ const logoutController = async (req, res) => {
|
|||
res.clearCookie('openid_id_token');
|
||||
res.clearCookie('openid_user_id');
|
||||
res.clearCookie('token_provider');
|
||||
clearCloudFrontCookies(res);
|
||||
clearCloudFrontCookies(res, {
|
||||
userId: req.user?.id ?? req.user?._id?.toString?.(),
|
||||
tenantId: req.user?.tenantId,
|
||||
});
|
||||
const response = { message };
|
||||
if (
|
||||
isOpenIdUser &&
|
||||
|
|
|
|||
|
|
@ -261,12 +261,15 @@ describe('LogoutController', () => {
|
|||
});
|
||||
|
||||
it('calls clearCloudFrontCookies on successful logout', async () => {
|
||||
const req = buildReq();
|
||||
const req = buildReq({ user: { _id: 'user1', tenantId: 'tenantA' } });
|
||||
const res = buildRes();
|
||||
|
||||
await logoutController(req, res);
|
||||
|
||||
expect(mockClearCloudFrontCookies).toHaveBeenCalledWith(res);
|
||||
expect(mockClearCloudFrontCookies).toHaveBeenCalledWith(res, {
|
||||
userId: 'user1',
|
||||
tenantId: 'tenantA',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ const verify2FAWithTempToken = async (req, res) => {
|
|||
delete userData.backupCodes;
|
||||
userData.id = user._id.toString();
|
||||
|
||||
const authToken = await setAuthTokens(user._id, res);
|
||||
const authToken = await setAuthTokens(user._id, res, null, req);
|
||||
return res.status(200).json({ token: authToken, user: userData });
|
||||
} catch (err) {
|
||||
logger.error('[verify2FAWithTempToken]', err);
|
||||
|
|
|
|||
|
|
@ -68,9 +68,12 @@ function createOAuthHandler(redirectUri = domains.client) {
|
|||
isEnabled(process.env.OPENID_REUSE_TOKENS) === true
|
||||
) {
|
||||
await syncUserEntraGroupMemberships(req.user, req.user.tokenset.access_token);
|
||||
setOpenIDAuthTokens(req.user.tokenset, req, res, req.user._id.toString());
|
||||
setOpenIDAuthTokens(req.user.tokenset, req, res, {
|
||||
userId: req.user._id.toString(),
|
||||
tenantId: req.user.tenantId,
|
||||
});
|
||||
} else {
|
||||
await setAuthTokens(req.user._id, res);
|
||||
await setAuthTokens(req.user._id, res, null, req);
|
||||
}
|
||||
res.redirect(redirectUri);
|
||||
} catch (err) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue