Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strong-insects-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use minor instead of patch anymore for this project

---

Migrated users.getPreferences to OpenAPI pattern with AJV validation
55 changes: 42 additions & 13 deletions apps/meteor/app/api/server/v1/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import type { IExportOperation, ILoginToken, IPersonalAccessToken, IUser, UserStatus } from '@rocket.chat/core-typings';
import { Users, Subscriptions, Sessions } from '@rocket.chat/models';
import {
ajv,
validateBadRequestErrorResponse,
validateUnauthorizedErrorResponse,
isUserCreateParamsPOST,
isUserSetActiveStatusParamsPOST,
isUserDeactivateIdleParamsPOST,
Expand All @@ -18,7 +21,7 @@
isUsersSetPreferencesParamsPOST,
isUsersCheckUsernameAvailabilityParamsGET,
isUsersSendConfirmationEmailParamsPOST,
ajv,

Check failure on line 24 in apps/meteor/app/api/server/v1/users.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

'ajv' is already defined
} from '@rocket.chat/rest-typings';
import { getLoginExpirationInMs, wrapExceptions } from '@rocket.chat/tools';
import { Accounts } from 'meteor/accounts-base';
Expand Down Expand Up @@ -830,25 +833,51 @@
},
);

API.v1.addRoute(
const UserPreferencesResponseSchema = {
type: 'object',
properties: {
preferences: {
type: 'object',
additionalProperties: true,
},
success: { type: 'boolean', enum: [true] },
},
required: ['preferences', 'success'],
additionalProperties: false,
};

const isUserPreferencesResponse = ajv.compile(UserPreferencesResponseSchema);

const usersEndpoints = API.v1.get(

Check failure on line 851 in apps/meteor/app/api/server/v1/users.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

'usersEndpoints' is already defined
'users.getPreferences',
{ authRequired: true },
{
async get() {
const user = await Users.findOneById(this.userId);
if (user?.settings) {
const { preferences = {} } = user?.settings;
preferences.language = user?.language;

return API.v1.success({
preferences,
});
}
return API.v1.failure(i18n.t('Accounts_Default_User_Preferences_not_available').toUpperCase());
authRequired: true,
response: {
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
200: isUserPreferencesResponse,
},
},
async function action() {
const user = await Users.findOneById(this.userId);

if (user?.settings) {
const { preferences = {} } = user.settings;
preferences.language = user.language;

return API.v1.success({ preferences });
}

throw new Meteor.Error('error-preferences-not-found', i18n.t('Accounts_Default_User_Preferences_not_available').toUpperCase());
},
);

export type UsersEndpoints = ExtractRoutesFromAPI<typeof usersEndpoints>;

declare module '@rocket.chat/rest-typings' {
type Endpoints = UsersEndpoints;
}

API.v1.addRoute(
'users.forgotPassword',
{ authRequired: false },
Expand Down Expand Up @@ -1501,7 +1530,7 @@
API.v1.updateRateLimiterDictionaryForRoute(userRegisterRoute, value);
});

type UsersEndpoints = ExtractRoutesFromAPI<typeof usersEndpoints>;

Check failure on line 1533 in apps/meteor/app/api/server/v1/users.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

'UsersEndpoints' is already defined

declare module '@rocket.chat/rest-typings' {
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
Expand Down
Loading