Skip to content

Commit

Permalink
Implement fetching avatar by user id
Browse files Browse the repository at this point in the history
  • Loading branch information
gabriellsh committed Oct 31, 2024
1 parent cced9ef commit 97701ee
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
3 changes: 2 additions & 1 deletion apps/meteor/server/routes/avatar/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { WebApp } from 'meteor/webapp';

import { roomAvatar } from './room';
import { userAvatarByUsername } from './user';
import { userAvatarByUsername, userAvatarById } from './user';

import './middlewares';

WebApp.connectHandlers.use('/avatar/room/', roomAvatar);
WebApp.connectHandlers.use('/avatar/uid/', userAvatarById);
WebApp.connectHandlers.use('/avatar/', userAvatarByUsername);
3 changes: 3 additions & 0 deletions apps/meteor/server/routes/avatar/middlewares/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ const getProtectAvatars = (callback?: typeof renderFallback) => async (req: Inco

// If unauthorized returns the SVG fallback (letter avatar)
export const protectAvatarsWithFallback = getProtectAvatars(renderFallback);

// Just returns 404
export const protectAvatars = getProtectAvatars();
3 changes: 2 additions & 1 deletion apps/meteor/server/routes/avatar/middlewares/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { WebApp } from 'meteor/webapp';

import { protectAvatarsWithFallback } from './auth';
import { protectAvatarsWithFallback, protectAvatars } from './auth';
import { handleBrowserVersionCheck } from './browserVersion';

WebApp.connectHandlers.use(handleBrowserVersionCheck);
WebApp.connectHandlers.use('/avatar/uid/', protectAvatars);
WebApp.connectHandlers.use('/avatar/', protectAvatarsWithFallback);
60 changes: 60 additions & 0 deletions apps/meteor/server/routes/avatar/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { NextFunction } from 'connect';

import { settings } from '../../../app/settings/server';
import { serveSvgAvatarInRequestedFormat, wasFallbackModified, setCacheAndDispositionHeaders, serveAvatarFile } from './utils';
import { IUser } from '@rocket.chat/apps-engine/definition/users';

const handleExternalProvider = async (externalProviderUrl: string, username: string, res: ServerResponse): Promise<void> => {
const response = await fetch(externalProviderUrl.replace('{username}', username));
Expand Down Expand Up @@ -72,3 +73,62 @@ export const userAvatarByUsername = async function (request: IncomingMessage, re

serveSvgAvatarInRequestedFormat({ nameOrUsername: requestUsername, req, res });
};

export const userAvatarById = async function (request: IncomingMessage, res: ServerResponse, next: NextFunction) {
const req = request as IIncomingMessage;

if (!req.url) {
return;
}

// replace removes the query string
const requestUserId = decodeURIComponent(req.url.slice(1).replace(/\?.*$/, ''));
if (!requestUserId) {
res.writeHead(404);
res.end();
return;
}

setCacheAndDispositionHeaders(req, res);

const externalProviderUrl = settings.get<string>('Accounts_AvatarExternalProviderUrl');
if (externalProviderUrl) {
const user = await Users.findOneById<Pick<IUser, 'name' | 'username'>>(requestUserId, { projection: { username: 1, name: 1 } });

if (!user?.username) {
res.writeHead(404);
res.end();
return;
}

void handleExternalProvider(externalProviderUrl, user.username, res);
return;
}

const file = await Avatars.findOneByUserId(requestUserId);
if (file) {
void serveAvatarFile(file, req, res, next);
return;
}

if (!wasFallbackModified(req.headers['if-modified-since'])) {
res.writeHead(304);
res.end();
return;
}

const user = await Users.findOneById<Pick<IUser, 'name' | 'username'>>(requestUserId, { projection: { username: 1, name: 1 } });
if (!user?.username) {
res.writeHead(404);
res.end();
return;
}

// Use real name for SVG letters
if (settings.get('UI_Use_Name_Avatar') && user?.name) {
serveSvgAvatarInRequestedFormat({ nameOrUsername: user.name, req, res });
return;
}

serveSvgAvatarInRequestedFormat({ nameOrUsername: user.username, req, res });
};

0 comments on commit 97701ee

Please sign in to comment.