summaryrefslogtreecommitdiff
path: root/packages/backend/src/server
diff options
context:
space:
mode:
authorHazelnoot <acomputerdog@gmail.com>2025-06-01 20:52:19 +0000
committerHazelnoot <acomputerdog@gmail.com>2025-06-01 20:52:19 +0000
commit39fcdcae257d158159d020ff72ef2c5e720f5ffa (patch)
treeb7cbef18463ddcc4a6b40ff03cfeed5ff4d992d3 /packages/backend/src/server
parentmerge: Overhaul trending polls (!1022) (diff)
parentcatch errors from fetchInstance() to resolve test errors (diff)
downloadsharkey-39fcdcae257d158159d020ff72ef2c5e720f5ffa.tar.gz
sharkey-39fcdcae257d158159d020ff72ef2c5e720f5ffa.tar.bz2
sharkey-39fcdcae257d158159d020ff72ef2c5e720f5ffa.zip
merge: Allow unauthenticated (logged-out) users to translate notes (!1055)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1055 Approved-by: dakkar <dakkar@thenautilus.net> Approved-by: Marie <github@yuugi.dev>
Diffstat (limited to 'packages/backend/src/server')
-rw-r--r--packages/backend/src/server/api/ApiCallService.ts16
-rw-r--r--packages/backend/src/server/api/endpoints.ts2
-rw-r--r--packages/backend/src/server/api/endpoints/notes/translate.ts13
3 files changed, 12 insertions, 19 deletions
diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts
index 0d2dafd556..5c9e5717bb 100644
--- a/packages/backend/src/server/api/ApiCallService.ts
+++ b/packages/backend/src/server/api/ApiCallService.ts
@@ -344,14 +344,14 @@ export class ApiCallService implements OnApplicationShutdown {
}
if (ep.meta.requireCredential || ep.meta.requireModerator || ep.meta.requireAdmin) {
- if (user == null) {
+ if (user == null && ep.meta.requireCredential !== 'optional') {
throw new ApiError({
message: 'Credential required.',
code: 'CREDENTIAL_REQUIRED',
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
httpStatusCode: 401,
});
- } else if (user!.isSuspended) {
+ } else if (user?.isSuspended) {
throw new ApiError({
message: 'Your account has been suspended.',
code: 'YOUR_ACCOUNT_SUSPENDED',
@@ -372,8 +372,8 @@ export class ApiCallService implements OnApplicationShutdown {
}
}
- if ((ep.meta.requireModerator || ep.meta.requireAdmin) && (this.meta.rootUserId !== user!.id)) {
- const myRoles = await this.roleService.getUserRoles(user!.id);
+ if ((ep.meta.requireModerator || ep.meta.requireAdmin) && (this.meta.rootUserId !== user?.id)) {
+ const myRoles = user ? await this.roleService.getUserRoles(user) : [];
if (ep.meta.requireModerator && !myRoles.some(r => r.isModerator || r.isAdministrator)) {
throw new ApiError({
message: 'You are not assigned to a moderator role.',
@@ -392,9 +392,9 @@ export class ApiCallService implements OnApplicationShutdown {
}
}
- if (ep.meta.requiredRolePolicy != null && (this.meta.rootUserId !== user!.id)) {
- const myRoles = await this.roleService.getUserRoles(user!.id);
- const policies = await this.roleService.getUserPolicies(user!.id);
+ if (ep.meta.requiredRolePolicy != null && (this.meta.rootUserId !== user?.id)) {
+ const myRoles = user ? await this.roleService.getUserRoles(user) : [];
+ const policies = await this.roleService.getUserPolicies(user ?? null);
if (!policies[ep.meta.requiredRolePolicy] && !myRoles.some(r => r.isAdministrator)) {
throw new ApiError({
message: 'You are not assigned to a required role.',
@@ -418,7 +418,7 @@ export class ApiCallService implements OnApplicationShutdown {
// Cast non JSON input
if ((ep.meta.requireFile || request.method === 'GET') && ep.params.properties) {
for (const k of Object.keys(ep.params.properties)) {
- const param = ep.params.properties![k];
+ const param = ep.params.properties[k];
if (['boolean', 'number', 'integer'].includes(param.type ?? '') && typeof data[k] === 'string') {
try {
data[k] = JSON.parse(data[k]);
diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts
index 0ba041c536..c7d884cce1 100644
--- a/packages/backend/src/server/api/endpoints.ts
+++ b/packages/backend/src/server/api/endpoints.ts
@@ -92,7 +92,7 @@ export type IEndpointMeta = (Omit<IEndpointMetaBase, 'requireCrential' | 'requir
}) | (Omit<IEndpointMetaBase, 'secure'> & {
secure: true,
}) | (Omit<IEndpointMetaBase, 'requireCredential' | 'kind'> & {
- requireCredential: true,
+ requireCredential: true | 'optional',
kind: (typeof permissions)[number],
}) | (Omit<IEndpointMetaBase, 'requireModerator' | 'kind'> & {
requireModerator: true,
diff --git a/packages/backend/src/server/api/endpoints/notes/translate.ts b/packages/backend/src/server/api/endpoints/notes/translate.ts
index e059b5e603..e55168e296 100644
--- a/packages/backend/src/server/api/endpoints/notes/translate.ts
+++ b/packages/backend/src/server/api/endpoints/notes/translate.ts
@@ -20,11 +20,9 @@ import { ApiError } from '../../error.js';
export const meta = {
tags: ['notes'],
- // TODO allow unauthenticated if default template allows?
- // Maybe a value 'optional' that allows unauthenticated OR a token w/ appropriate role.
- // This will allow unauthenticated requests without leaking post data to restricted clients.
- requireCredential: true,
+ requireCredential: 'optional',
kind: 'read:account',
+ requiredRolePolicy: 'canUseTranslator',
res: {
type: 'object',
@@ -88,17 +86,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
private readonly loggerService: ApiLoggerService,
) {
super(meta, paramDef, async (ps, me) => {
- const policies = await this.roleService.getUserPolicies(me.id);
- if (!policies.canUseTranslator) {
- throw new ApiError(meta.errors.unavailable);
- }
-
const note = await this.getterService.getNote(ps.noteId).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote);
throw err;
});
- if (!(await this.noteEntityService.isVisibleForMe(note, me.id))) {
+ if (!(await this.noteEntityService.isVisibleForMe(note, me?.id ?? null))) {
throw new ApiError(meta.errors.cannotTranslateInvisibleNote);
}