Files

56 lines
2.1 KiB
JavaScript

// utils/resolveAvatar.util.js
//
// Resolves a stored avatar into a browser-usable reference at read time.
//
// personal_info.avatar is never handed to the browser as a raw S3 URL —
// same protection as every other media type in this app (see
// controllers/client/media.controller.js): the browser only ever gets a
// short-lived opaque stream_token, proxied through
// GET /client/media/stream/:token, which mints the real presigned URL
// server-side and pipes the bytes back. The real bucket/key/signature never
// reach the DOM.
//
// - S3-stored avatars (avatar.uuid present) → sign a fresh media JWT from
// the stored key on every read (never persist a token/URL on the row).
// - Google-picture avatars (reg_type: 'google', no uuid — see
// auth.controller.js googleCallback) are an external CDN URL and pass
// through unchanged as file_url; there's nothing of ours to sign or hide.
//
const { signMediaToken } = require('../services/mediaToken.service');
async function resolveAvatarUrl(avatar) {
if (!avatar) return avatar ?? null;
if (!avatar.uuid) {
// External URL (e.g. Google) — nothing to sign, just normalize the field
// name to match the { stream_token?, file_url? } shape resolveAssetSrc()
// already expects for every other media payload.
return { ...avatar, url: undefined, file_url: avatar.url };
}
const token = signMediaToken({
storage_key: avatar.uuid,
file_type: 'image',
mime_type: avatar.mime_type,
});
return { ...avatar, url: undefined, file_url: undefined, stream_token: token };
}
// Mutates-and-returns a shallow copy of a user (plain object or Sequelize
// instance) with personal_info.avatar resolved. Safe to call on a user with
// no avatar at all.
async function resolveUserAvatar(user) {
if (!user) return user;
const u = user.toJSON ? user.toJSON() : { ...user };
if (!u.personal_info?.avatar) return u;
u.personal_info = {
...u.personal_info,
avatar: await resolveAvatarUrl(u.personal_info.avatar),
};
return u;
}
module.exports = { resolveAvatarUrl, resolveUserAvatar };