From a13e956af00b0acdafcc22d4067b63459bc03bc4 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sun, 16 Oct 2022 00:46:13 +0200 Subject: [PATCH 001/108] make authorization token granting OAuth 2.0 compatible This is basically a shim on top of the existing API. Instead of the 3rd party, the web UI generates the authorization session. The data that the API returns is slightly adjusted so that only one API call is necessary instead of two. --- locales/en-US.yml | 2 + .../api/endpoints/auth/session/generate.ts | 40 ++++-- packages/client/src/pages/auth.vue | 117 ++++++++++++++---- packages/client/src/router.ts | 3 + 4 files changed, 134 insertions(+), 28 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index a6a8a2110..10e0e4c65 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -828,6 +828,8 @@ setTag: "Set tag" addTag: "Add tag" removeTag: "Remove tag" externalCssSnippets: "Some CSS snippets for your inspiration (not managed by FoundKey)" +oauthErrorGoBack: "An error happened while trying to authenticate a 3rd party app.\ + \ Please go back and try again." _emailUnavailable: used: "This email address is already being used" format: "The format of this email address is invalid" diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts index eeb51abc6..e1b498a49 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/generate.ts @@ -23,6 +23,19 @@ export const meta = { optional: false, nullable: false, format: 'url', }, + // stuff that auth/session/show would respond with + id: { + type: 'string', + description: 'The ID of the authentication session. Same as returned by `auth/session/show`.', + optional: false, nullable: false, + format: 'id', + }, + app: { + type: 'object', + description: 'The App requesting permissions. Same as returned by `auth/session/show`.', + optional: false, nullable: false, + ref: 'App', + }, }, }, @@ -30,17 +43,27 @@ export const meta = { } as const; export const paramDef = { - type: 'object', - properties: { - appSecret: { type: 'string' }, - }, - required: ['appSecret'], + oneOf: [{ + type: 'object', + properties: { + clientId: { type: 'string' }, + }, + required: ['clientId'] + }, { + type: 'object', + properties: { + appSecret: { type: 'string' }, + }, + required: ['appSecret'], + }], } as const; // eslint-disable-next-line import/no-default-export export default define(meta, paramDef, async (ps) => { // Lookup app - const app = await Apps.findOneBy({ + const app = await Apps.findOneBy(ps.clientId ? { + id: ps.clientId, + } : { secret: ps.appSecret, }); @@ -50,10 +73,11 @@ export default define(meta, paramDef, async (ps) => { // Generate token const token = uuid(); + const id = genId(); // Create session token document const doc = await AuthSessions.insert({ - id: genId(), + id, createdAt: new Date(), appId: app.id, token, @@ -62,5 +86,7 @@ export default define(meta, paramDef, async (ps) => { return { token: doc.token, url: `${config.authUrl}/${doc.token}`, + id, + app: await Apps.pack(app), }; }); diff --git a/packages/client/src/pages/auth.vue b/packages/client/src/pages/auth.vue index 3b3ff7bac..ac9a3e051 100644 --- a/packages/client/src/pages/auth.vue +++ b/packages/client/src/pages/auth.vue @@ -6,7 +6,7 @@ ref="form" class="form" :session="session" - @denied="state = 'denied'" + @denied="denied" @accepted="accepted" />
@@ -20,6 +20,9 @@

{{ i18n.ts.somethingHappened }}

+
+

{{ i18n.ts.oauthErrorGoBack }}

+
@@ -37,43 +40,115 @@ import { i18n } from '@/i18n'; import { query, appendQuery } from '@/scripts/url'; const props = defineProps<{ - token: string; + token?: string; }>(); -let state: 'fetching' | 'waiting' | 'denied' | 'accepted' | 'fetch-session-error' = $ref('fetching'); +let state: 'fetching' | 'waiting' | 'denied' | 'accepted' | 'fetch-session-error' | 'oauth-error' = $ref('fetching'); let session = $ref(null); -onMounted(() => { +// if this is an OAuth request, will contain the respective parameters +let oauth: { state: string | null, callback: string } | null = null; + +onMounted(async () => { if (!$i) return; - // Fetch session - os.api('auth/session/show', { - token: props.token, - }).then(fetchedSession => { - session = fetchedSession; + // detect whether this is actual OAuth or "legacy" auth + const params = new URLSearchParams(location.search); + if (params.get('response_type') === 'code') { + // OAuth request detected! - // 既に連携していた場合 - if (session.app.isAuthorized) { - os.api('auth/accept', { - token: session.token, - }).then(() => { - this.accepted(); - }); - } else { - state = 'waiting'; + // as a kind of hack, we first have to start the session for the OAuth client + const clientId = params.get('client_id'); + if (!clientId) { + state = 'fetch-session-error'; + return; } - }).catch(() => { + + session = await os.api('auth/session/generate', { + clientId, + }).catch(e => { + const response = { + error: 'server_error', + ...(oauth.state ? { state: oauth.state } : {}), + }; + // try to determine the cause of the error + if (e.code === 'NO_SUCH_APP') { + response.error = 'invalid_request'; + response.error_description = 'unknown client_id'; + } else if (e.message) { + response.error_description = e.message; + } + + if (params.has('redirect_uri')) { + location.href = appendQuery(params.get('redirect_uri'), query(response)); + } else { + state = 'oauth-error'; + } + }); + + oauth = { + state: params.get('state'), + callback: params.get('redirect_uri') ?? session.app.callbackUrl, + }; + } else if (!props.token) { state = 'fetch-session-error'; - }); + } else { + session = await os.api('auth/session/show', { + token: props.token, + }).catch(() => { + state = 'fetch-session-error'; + }); + } + + // abort if an error occurred + if (['fetch-session-error', 'oauth-error'].includes(state)) return; + + // check whether the user already authorized the app earlier + if (session.app.isAuthorized) { + // already authorized, move on through! + os.api('auth/accept', { + token: session.token, + }).then(() => { + accepted(); + }); + } else { + // user still has to give consent + state = 'waiting'; + } }); function accepted(): void { state = 'accepted'; - if (session.app.callbackUrl) { + if (oauth) { + // redirect with authorization token + const params = { + code: session.token, + ...(oauth.state ? { state: oauth.state } : {}), + }; + + location.href = appendQuery(oauth.callback, query(params)); + } else if (session.app.callbackUrl) { + // do whatever the legacy auth did location.href = appendQuery(session.app.callbackUrl, query({ token: session.token })); } } +function denied(): void { + state = 'denied'; + if (oauth) { + // redirect with error code + const params = { + error: 'access_denied', + error_description: 'The user denied permission.', + ...(oauth.state ? { state: oauth.state } : {}), + }; + + location.href = appendQuery(oauth.callback, query(params)); + } else { + // legacy auth didn't do anything in this case... + } +} + function onLogin(res): void { login(res.i); } diff --git a/packages/client/src/router.ts b/packages/client/src/router.ts index 6d3011688..791076e71 100644 --- a/packages/client/src/router.ts +++ b/packages/client/src/router.ts @@ -94,6 +94,9 @@ export const routes = [{ }, { path: '/preview', component: page(() => import('./pages/preview.vue')), +}, { + path: '/auth', + component: page(() => import('./pages/auth.vue')), }, { path: '/auth/:token', component: page(() => import('./pages/auth.vue')), From 7db7fdd9e2d7114fa8c99aa0bfe9d88ac043536a Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sun, 16 Oct 2022 01:11:47 +0200 Subject: [PATCH 002/108] add API route for OAuth access token retrieval --- .../backend/src/server/api/common/oauth.ts | 94 +++++++++++++++++++ .../api/endpoints/auth/session/oauth.ts | 5 + packages/backend/src/server/api/index.ts | 4 + 3 files changed, 103 insertions(+) create mode 100644 packages/backend/src/server/api/common/oauth.ts create mode 100644 packages/backend/src/server/api/endpoints/auth/session/oauth.ts diff --git a/packages/backend/src/server/api/common/oauth.ts b/packages/backend/src/server/api/common/oauth.ts new file mode 100644 index 000000000..731cd73fa --- /dev/null +++ b/packages/backend/src/server/api/common/oauth.ts @@ -0,0 +1,94 @@ +import Koa from 'koa'; +import { IsNull, Not } from 'typeorm'; +import { Apps, AuthSessions, AccessTokens } from '@/models/index.js'; +import config from '@/config/index.js'; + +export async function oauth(ctx: Koa.Context): void { + const { + grant_type, + code, + // TODO: check redirect_uri + // since this is also not checked in the legacy app authentication + // it seems pointless to check it here, and it is also not stored. + redirect_uri, + } = ctx.request.body; + + // check if any of the parameters are null or empty string + if ([grant_type, code].some(x => !x)) { + ctx.response.status = 400; + ctx.response.body = { + error: 'invalid_request', + }; + return; + } + + if (grant_type !== 'authorization_code') { + ctx.response.status = 400; + ctx.response.body = { + error: 'unsupported_grant_type', + error_description: 'only authorization_code grants are supported', + }; + return; + } + + const authHeader = ctx.headers.authorization; + if (!authHeader?.toLowerCase().startsWith('basic ')) { + ctx.response.status = 401; + ctx.response.set('WWW-Authenticate', 'Basic'); + ctx.response.body = { + error: 'invalid_client', + error_description: 'HTTP Basic Authentication required', + }; + return; + } + + const [client_id, client_secret] = new Buffer(authHeader.slice(6), 'base64') + .toString('ascii') + .split(':', 2); + + const [app, session] = await Promise.all([ + Apps.findOneBy({ + id: client_id, + secret: client_secret, + }), + AuthSessions.findOneBy({ + appId: client_id, + token: code, + // only check for approved auth sessions + userId: Not(IsNull()), + }), + ]); + if (app == null) { + ctx.response.status = 401; + ctx.response.set('WWW-Authenticate', 'Basic'); + ctx.response.body = { + error: 'invalid_client', + error_description: 'authentication failed', + }; + return; + } + if (session == null) { + ctx.response.status = 400; + ctx.response.body = { + error: 'invalid_grant', + }; + return; + } + + const [ token ] = await Promise.all([ + AccessTokens.findOneByOrFail({ + appId: client_id, + userId: session.userId, + }), + // session is single use + AuthSessions.delete(session.id), + ]); + + ctx.response.status = 200; + ctx.response.body = { + access_token: token.token, + token_type: 'bearer', + // FIXME: per-token permissions + scope: app.permission.join(' '), + }; +}; diff --git a/packages/backend/src/server/api/endpoints/auth/session/oauth.ts b/packages/backend/src/server/api/endpoints/auth/session/oauth.ts new file mode 100644 index 000000000..d6aa6caab --- /dev/null +++ b/packages/backend/src/server/api/endpoints/auth/session/oauth.ts @@ -0,0 +1,5 @@ +/* +This route is already in use, but the functionality is provided +by '@/server/api/common/oauth.ts'. The route is not here because +that route requires more deep level access to HTTP data. +*/ diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts index 140649dcc..456f5ff11 100644 --- a/packages/backend/src/server/api/index.ts +++ b/packages/backend/src/server/api/index.ts @@ -15,6 +15,7 @@ import { handler } from './api-handler.js'; import signup from './private/signup.js'; import signin from './private/signin.js'; import signupPending from './private/signup-pending.js'; +import { oauth } from './common/oauth.js'; import discord from './service/discord.js'; import github from './service/github.js'; import twitter from './service/twitter.js'; @@ -74,6 +75,9 @@ for (const endpoint of endpoints) { } } +// the OAuth endpoint does some shenanigans and can not use the normal API handler +router.post('/auth/session/oauth', oauth); + router.post('/signup', signup); router.post('/signin', signin); router.post('/signup-pending', signupPending); From 2b19b341962f0d7122f77646768127c16f47698c Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sat, 15 Oct 2022 16:14:16 +0200 Subject: [PATCH 003/108] update OpenAPI docs to OAuth --- packages/backend/src/misc/api-permissions.ts | 71 ++++++++++--------- .../src/server/api/openapi/gen-spec.ts | 26 +++++-- 2 files changed, 56 insertions(+), 41 deletions(-) diff --git a/packages/backend/src/misc/api-permissions.ts b/packages/backend/src/misc/api-permissions.ts index 160cdf9fd..c086286c9 100644 --- a/packages/backend/src/misc/api-permissions.ts +++ b/packages/backend/src/misc/api-permissions.ts @@ -1,35 +1,38 @@ -export const kinds = [ - 'read:account', - 'write:account', - 'read:blocks', - 'write:blocks', - 'read:drive', - 'write:drive', - 'read:favorites', - 'write:favorites', - 'read:following', - 'write:following', - 'read:messaging', - 'write:messaging', - 'read:mutes', - 'write:mutes', - 'write:notes', - 'read:notifications', - 'write:notifications', - 'read:reactions', - 'write:reactions', - 'write:votes', - 'read:pages', - 'write:pages', - 'write:page-likes', - 'read:page-likes', - 'read:user-groups', - 'write:user-groups', - 'read:channels', - 'write:channels', - 'read:gallery', - 'write:gallery', - 'read:gallery-likes', - 'write:gallery-likes', -]; // IF YOU ADD KINDS(PERMISSIONS), YOU MUST ADD TRANSLATIONS (under _permissions). + +// short English descriptions used for the documentation +export const descriptions = { + 'read:account': 'Read the accounts data.', + 'write:account': 'Write the accounts data.', + 'read:blocks': 'Read which users are blocked.', + 'write:blocks': 'Create, change and delete blocks.', + 'read:drive': 'List files and folders in the drive.', + 'write:drive': 'Create, change and delete files from the drive.', + 'read:favourites': 'List favourited notes.', + 'write:favourites': 'Favourite or unfavourite notes.', + 'read:following': 'Read who the user is following.', + 'write:following': 'Follow or unfollow other users.', + 'read:messaging': 'Read chat messages and history.', + 'write:messaging': 'Create and delete chat messages.', + 'read:mutes': 'List users which are muted or whose renotes are muted.', + 'write:mutes': 'Create or delete (renote) mutes.', + 'write:notes': 'Create or delete notes.', + 'read:notifications': 'Read notifications.', + 'write:notifications': 'Mark notifications as read or create notifications.', + 'write:reactions': 'Create or delete reactions.', + 'write:votes': 'Vote in polls.', + 'read:pages': 'List and read pages.', + 'write:pages': 'Create, modify and delete pages.', + 'read:page-likes': 'List page likes.', + 'write:page-likes': 'Like or unlike pages.', + 'read:user-groups': 'List joined, owned and invited to groups.', + 'write:user-groups': 'Create, modify, delete, transfer, join, or leave groups. Invite or ban others from groups. Accept or reject group invitations.', + 'read:channels': 'List followed and owned channels.', + 'write:channels': 'Create, modify, follow or unfollow channels.', + 'read:gallery': 'Read gallery posts.', + 'write:gallery': 'Create, modify or delete gallery posts.', + 'read:gallery-likes': 'List which gallery posts are liked.', + 'write:gallery-likes': 'Like or unlike gallery posts.', +}; + +export const kinds = Object.keys(descriptions); diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index f9795884d..b79558456 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -3,6 +3,7 @@ import { errors as errorDefinitions } from '../error.js'; import endpoints from '../endpoints.js'; import { schemas, convertSchemaToOpenApiSchema } from './schemas.js'; import { httpCodes } from './http-codes.js'; +import { descriptions as scopes } from '@/misc/api-permissions.js'; export function genOpenapiSpec() { const spec = { @@ -34,10 +35,15 @@ export function genOpenapiSpec() { in: 'body', name: 'i', }, - // TODO: change this to oauth2 when the remaining oauth stuff is set up - Bearer: { - type: 'http', - scheme: 'bearer', + OAuth: { + type: 'oauth2', + flows: { + authorizationCode: { + authorizationUrl: `${config.url}/auth`, + tokenUrl: `${config.apiUrl}/auth/session/oauth`, + scopes, + }, + }, }, }, }, @@ -137,10 +143,16 @@ export function genOpenapiSpec() { { ApiKeyAuth: [], }, - { - Bearer: [], - }, ]; + if (endpoint.meta.kind) { + security.push({ + OAuth: [endpoint.meta.kind], + }); + } else { + security.push({ + OAuth: [], + }); + } if (!endpoint.meta.requireCredential) { // add this to make authentication optional security.push({}); From 418c88bb8fb48f54dfe14f884143f9956f42be55 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sun, 16 Oct 2022 06:24:55 +0200 Subject: [PATCH 004/108] expire AuthSessions after 15 min --- .../backend/src/queue/processors/system/check-expired.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/queue/processors/system/check-expired.ts b/packages/backend/src/queue/processors/system/check-expired.ts index 5608dc43c..fe7012b1d 100644 --- a/packages/backend/src/queue/processors/system/check-expired.ts +++ b/packages/backend/src/queue/processors/system/check-expired.ts @@ -1,6 +1,6 @@ import Bull from 'bull'; import { In, LessThan } from 'typeorm'; -import { AttestationChallenges, Mutings, PasswordResetRequests, Signins } from '@/models/index.js'; +import { AttestationChallenges, AuthSessions, Mutings, PasswordResetRequests, Signins } from '@/models/index.js'; import { publishUserEvent } from '@/services/stream.js'; import { MINUTE, DAY } from '@/const.js'; import { queueLogger } from '@/queue/logger.js'; @@ -40,7 +40,11 @@ export async function checkExpired(job: Bull.Job>, done: createdAt: LessThan(new Date(new Date().getTime() - 30 * MINUTE)), }); - logger.succ('Deleted expired mutes, signins and attestation challenges.'); + await AuthSessions.delete({ + createdAt: LessThan(new Date(new Date().getTime() - 15 * MINUTE)), + }); + + logger.succ('Deleted expired data.'); done(); } From c65fdebe2615068a02c6e8c5653f17d3fec4edfd Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sun, 16 Oct 2022 20:59:21 +0200 Subject: [PATCH 005/108] server: add missing auth/deny endpoint This endpoint is hinted at in the client, but is not actually defined in the backend. This commit defines it. --- packages/backend/src/server/api/endpoints.ts | 2 + .../src/server/api/endpoints/auth/deny.ts | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 packages/backend/src/server/api/endpoints/auth/deny.ts diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index 3237935d5..c85bb6632 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -67,6 +67,7 @@ import * as ep___ap_show from './endpoints/ap/show.js'; import * as ep___app_create from './endpoints/app/create.js'; import * as ep___app_show from './endpoints/app/show.js'; import * as ep___auth_accept from './endpoints/auth/accept.js'; +import * as ep___auth_deny from './endpoints/auth/deny.js'; import * as ep___auth_session_generate from './endpoints/auth/session/generate.js'; import * as ep___auth_session_show from './endpoints/auth/session/show.js'; import * as ep___auth_session_userkey from './endpoints/auth/session/userkey.js'; @@ -375,6 +376,7 @@ const eps = [ ['app/create', ep___app_create], ['app/show', ep___app_show], ['auth/accept', ep___auth_accept], + ['auth/deny', ep___auth_deny], ['auth/session/generate', ep___auth_session_generate], ['auth/session/show', ep___auth_session_show], ['auth/session/userkey', ep___auth_session_userkey], diff --git a/packages/backend/src/server/api/endpoints/auth/deny.ts b/packages/backend/src/server/api/endpoints/auth/deny.ts new file mode 100644 index 000000000..ca1a585c7 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/auth/deny.ts @@ -0,0 +1,38 @@ +import { AuthSessions } from '@/models/index.js'; +import define from '../../define.js'; +import { ApiError } from '../../error.js'; + +export const meta = { + tags: ['auth'], + + requireCredential: true, + + secure: true, + + errors: { + noSuchSession: { + message: 'No such session.', + code: 'NO_SUCH_SESSION', + id: '9c72d8de-391a-43c1-9d06-08d29efde8df', + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + token: { type: 'string' }, + }, + required: ['token'], +} as const; + +// eslint-disable-next-line import/no-default-export +export default define(meta, paramDef, async (ps, user) => { + const result = await AuthSessions.delete({ + token: ps.token, + }); + + if (result.affected == 0) { + throw new ApiError(meta.errors.noSuchSession); + } +}); From c5568cfdf3f9d414ec8b387cba95e5a313230792 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sun, 16 Oct 2022 21:09:30 +0200 Subject: [PATCH 006/108] client: fix auth page layout This also includes better rendering when no permissions are requested. Also removed the app's id from the page as it makes no sense to show this to a user. Changelog: Fixed --- locales/en-US.yml | 2 + packages/client/src/pages/auth.form.vue | 6 ++- packages/client/src/pages/auth.vue | 68 ++++++++++++++----------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index 10e0e4c65..2051d16c2 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -830,6 +830,8 @@ removeTag: "Remove tag" externalCssSnippets: "Some CSS snippets for your inspiration (not managed by FoundKey)" oauthErrorGoBack: "An error happened while trying to authenticate a 3rd party app.\ \ Please go back and try again." +appAuthorization: "App authorization" +noPermissionsRequested: "(No permissions requested.)" _emailUnavailable: used: "This email address is already being used" format: "The format of this email address is invalid" diff --git a/packages/client/src/pages/auth.form.vue b/packages/client/src/pages/auth.form.vue index d4af3b6db..035ffac9a 100644 --- a/packages/client/src/pages/auth.form.vue +++ b/packages/client/src/pages/auth.form.vue @@ -3,14 +3,16 @@
{{ i18n.t('_auth.shareAccess', { name: app.name }) }}

{{ app.name }}

-

{{ app.id }}

{{ app.description }}

{{ i18n.ts._auth.permissionAsk }}

-
    +
    • {{ i18n.t(`_permissions.${p}`) }}
    +

{{ i18n.ts._auth.permissionAsk }}

-
    -
  • {{ i18n.t(`_permissions.${p}`) }}
  • +
      +
    • {{ i18n.t(`_permissions.${p}`) }}
    From 7e8d5c3b79ae37747c3c3561f42142c6a529d2f7 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 6 Dec 2022 21:52:16 +0100 Subject: [PATCH 031/108] foundkey-js: remove integration fields from instance type --- packages/foundkey-js/src/entities.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/foundkey-js/src/entities.ts b/packages/foundkey-js/src/entities.ts index 3616dc445..2fd05c1cf 100644 --- a/packages/foundkey-js/src/entities.ts +++ b/packages/foundkey-js/src/entities.ts @@ -277,9 +277,6 @@ export type LiteInstanceMetadata = { swPublickey: string | null; maxNoteTextLength: number; enableEmail: boolean; - enableTwitterIntegration: boolean; - enableGithubIntegration: boolean; - enableDiscordIntegration: boolean; enableServiceWorker: boolean; emojis: CustomEmoji[]; iconUrl: string; From 87e1e658f2975fa07c1db7730b898047abaf4b63 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 6 Dec 2022 22:03:34 +0100 Subject: [PATCH 032/108] locales: remove integration-related locales --- locales/ar-SA.yml | 4 ---- locales/bn-BD.yml | 4 ---- locales/cs-CZ.yml | 4 ---- locales/de-DE.yml | 16 ---------------- locales/en-US.yml | 14 -------------- locales/es-ES.yml | 4 ---- locales/fr-FR.yml | 16 ---------------- locales/id-ID.yml | 4 ---- locales/it-IT.yml | 4 ---- locales/ja-JP.yml | 14 -------------- locales/ja-KS.yml | 2 -- locales/kab-KAB.yml | 1 - locales/ko-KR.yml | 4 ---- locales/pl-PL.yml | 4 ---- locales/ro-RO.yml | 4 ---- locales/ru-RU.yml | 4 ---- locales/sk-SK.yml | 4 ---- locales/uk-UA.yml | 4 ---- locales/vi-VN.yml | 4 ---- locales/zh-CN.yml | 4 ---- locales/zh-TW.yml | 4 ---- 21 files changed, 123 deletions(-) diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 8493f72ba..74869f65a 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -293,9 +293,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "الصفحات" -integration: "التكامل" -connectService: "اتصل" -disconnectService: "اقطع الاتصال" enableLocalTimeline: "تفعيل الخيط المحلي" enableGlobalTimeline: "تفعيل الخيط الزمني الشامل" disablingTimelinesInfo: "سيتمكن المديرون والمشرفون من الوصول إلى كل الخيوط الزمنية\ @@ -402,7 +399,6 @@ normalPassword: "الكلمة السرية جيدة" strongPassword: "الكلمة السرية قوية" passwordMatched: "التطابق صحيح!" passwordNotMatched: "غير متطابقتان" -signinWith: "الولوج عبر {x}" signinFailed: "فشل الولوج، خطأ في اسم المستخدم أو كلمة المرور." tapSecurityKey: "أنقر مفتاح الأمان" or: "أو" diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index 9cee3b901..cdaac8b2d 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -308,9 +308,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "পৃষ্ঠা" -integration: "ইন্টিগ্রেশন" -connectService: "সংযুক্ত করুন" -disconnectService: "সংযোগ বিচ্ছিন্ন করুন" enableLocalTimeline: "স্থানীয় টাইমলাইন চালু করুন" enableGlobalTimeline: "গ্লোবাল টাইমলাইন চালু করুন" disablingTimelinesInfo: "আপনি এই টাইমলাইনগুলি বন্ধ করলেও প্রশাসক এবং মডারেটররা এই\ @@ -417,7 +414,6 @@ normalPassword: "সাধারণ পাসওয়ার্ড" strongPassword: "শক্তিশালী পাসওয়ার্ড" passwordMatched: "মিলেছে" passwordNotMatched: "মিলেনি" -signinWith: "{x} এর সাহায্যে সাইন ইন করুন" signinFailed: "লগ ইন করা যায়নি। আপনার ব্যবহারকারীর নাম এবং পাসওয়ার্ড চেক করুন." tapSecurityKey: "সিকিউরিটি কী স্পর্শ করুন" or: "অথবা" diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index 69e01db57..53c7f4aa4 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -277,9 +277,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Stránky" -integration: "Integrace" -connectService: "Připojit" -disconnectService: "Odpojit" enableLocalTimeline: "Povolit lokální čas" enableGlobalTimeline: "Povolit globální čas" enableRegistration: "Povolit registraci novým uživatelům" @@ -353,7 +350,6 @@ normalPassword: "Dobré heslo" strongPassword: "Silné heslo" passwordMatched: "Hesla se schodují" passwordNotMatched: "Hesla se neschodují" -signinWith: "Přihlásit se s {x}" signinFailed: "Nelze se přihlásit. Zkontrolujte prosím své uživatelské jméno a heslo." or: "Nebo" language: "Jazyk" diff --git a/locales/de-DE.yml b/locales/de-DE.yml index aa97782f0..ff6e082ab 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -321,9 +321,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Seiten" -integration: "Integration" -connectService: "Verbinden" -disconnectService: "Trennen" enableLocalTimeline: "Lokale Chronik aktivieren" enableGlobalTimeline: "Globale Chronik aktivieren" disablingTimelinesInfo: "Administratoren und Moderatoren haben immer Zugriff auf alle\ @@ -433,7 +430,6 @@ normalPassword: "Durchschnittliches Passwort" strongPassword: "Starkes Passwort" passwordMatched: "Stimmt überein" passwordNotMatched: "Stimmt nicht überein" -signinWith: "Mit {x} anmelden" signinFailed: "Anmeldung fehlgeschlagen. Überprüfe Benutzername und Passswort." tapSecurityKey: "Tippe deinen Sicherheitsschlüssel an" or: "Oder" @@ -1373,18 +1369,6 @@ recommended: "Empfehlung" check: "Check" maxCustomEmojiPicker: Maximale Anzahl vorgeschlagener benutzerdefinierter Emoji maxUnicodeEmojiPicker: Maximale Anzahl vorgeschlagener Unicode-Emoji -_services: - _discord: - connected: 'Discord: @{username}#{discriminator} wurde mit Foundkey-Account @{mkUsername} - verknüpft!' - disconnected: Discord-Verknüpfung wurde entfernt. - _twitter: - connected: Twitter-Account @{twitterUserName} wurde mit Foundkey-Account @{userName} - verknüpft! - disconnected: Twitter-Verknüpfung wurde entfernt. - _github: - connected: GitHub-Account @{login} wurde mit Foundkey-Account @{userName} verknüpft! - disconnected: GitHub-Verknüpfung wurde entfernt. documentation: Dokumentation signinHistoryExpires: Frühere Login-Versuche werden aus Datenschutzgründen nach 60 Tagen automatisch gelöscht. diff --git a/locales/en-US.yml b/locales/en-US.yml index 75d2643f0..bc6d47502 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -311,9 +311,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Pages" -integration: "Integration" -connectService: "Connect" -disconnectService: "Disconnect" enableLocalTimeline: "Enable local timeline" enableGlobalTimeline: "Enable global timeline" disablingTimelinesInfo: "Adminstrators and Moderators will always have access to all\ @@ -420,7 +417,6 @@ normalPassword: "Average password" strongPassword: "Strong password" passwordMatched: "Matches" passwordNotMatched: "Does not match" -signinWith: "Sign in with {x}" signinFailed: "Unable to sign in. The entered username or password is incorrect." tapSecurityKey: "Tap your security key" or: "Or" @@ -1344,16 +1340,6 @@ _deck: list: "List" mentions: "Mentions" direct: "Direct notes" -_services: - _discord: - connected: "Discord: @{username}#{discriminator} connected to FoundKey: @{mkUsername}!" - disconnected: "Discord linkage has been removed." - _twitter: - connected: "Twitter: @{twitterUserName} connected to FoundKey: @{userName}!" - disconnected: "Twitter linkage has been removed." - _github: - connected: "GitHub: @{login} connected to FoundKey: @{userName}!" - disconnected: "GitHub linkage has been removed." _translationService: _deepl: authKey: "DeepL Auth Key" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 969639f9b..8e022fa27 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -311,9 +311,6 @@ dayX: "Día {day}" monthX: "Mes {month}" yearX: "Año {year}" pages: "Páginas" -integration: "Integración" -connectService: "Conectar" -disconnectService: "Desconectar" enableLocalTimeline: "Habilitar linea de tiempo local" enableGlobalTimeline: "Habilitar linea de tiempo global" disablingTimelinesInfo: "Aunque se desactiven estas lineas de tiempo, por conveniencia\ @@ -420,7 +417,6 @@ normalPassword: "Buena contraseña" strongPassword: "Muy buena contraseña" passwordMatched: "Correcto" passwordNotMatched: "Las contraseñas no son las mismas" -signinWith: "Inicie sesión con {x}" signinFailed: "Autenticación fallida. Asegúrate de haber usado el nombre de usuario\ \ y contraseña correctos." tapSecurityKey: "Toque la clave de seguridad" diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index 5150905cb..1cbcb20a4 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -311,9 +311,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Pages" -integration: "Intégrations" -connectService: "Connexion" -disconnectService: "Déconnexion" enableLocalTimeline: "Activer le fil local" enableGlobalTimeline: "Activer le fil global" disablingTimelinesInfo: "Même si vous désactivez ces fils, les administrateur·rice·s\ @@ -423,7 +420,6 @@ normalPassword: "Mot de passe acceptable" strongPassword: "Mot de passe fort" passwordMatched: "Les mots de passe correspondent" passwordNotMatched: "Les mots de passe ne correspondent pas" -signinWith: "Se connecter avec {x}" signinFailed: "Échec d’authentification. Veuillez vérifier que votre nom d’utilisateur\ \ et mot de passe sont corrects." tapSecurityKey: "Appuyez sur votre clé de sécurité" @@ -1331,18 +1327,6 @@ _deck: list: "Listes" mentions: "Mentions" direct: "Direct" -_services: - _discord: - connected: '@{username}#{discriminator} sur Discord est connecté à @{mkUsername} - sur FoundKey !' - disconnected: La liaison avec Discord à été supprimée. - _twitter: - connected: '@{twitterUserName} sur Twitter est connecté à @{userName} sur FoundKey - !' - disconnected: La liaison avec Twitter à été supprimée. - _github: - disconnected: La liaison avec Github à été supprimée. - connected: '@{login} sur Github est connecté à @{userName} sur FoundKey !' exportAll: Tout exporter stopActivityDeliveryDescription: L'activité locale ne sera pas envoyé à cette instance. La réception de l'activité continuera de fonctionner comme avant. diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 585a64499..5e9ba9b46 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -310,9 +310,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Halaman" -integration: "Integrasi" -connectService: "Sambungkan" -disconnectService: "Putuskan" enableLocalTimeline: "Nyalakan linimasa lokal" enableGlobalTimeline: "Nyalakan linimasa global" disablingTimelinesInfo: "Admin dan Moderator akan selalu memiliki akses ke semua linimasa\ @@ -419,7 +416,6 @@ normalPassword: "Kata sandi baik" strongPassword: "Kata sandi kuat" passwordMatched: "Kata sandi sama" passwordNotMatched: "Kata sandi tidak sama" -signinWith: "Masuk dengan {x}" signinFailed: "Tidak dapat masuk. Nama pengguna atau kata sandi yang kamu masukkan\ \ salah." tapSecurityKey: "Ketuk kunci keamanan kamu" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index f502484d0..da6a6a7af 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -304,9 +304,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Pagine" -integration: "App collegate" -connectService: "Connessione" -disconnectService: "Disconnessione " enableLocalTimeline: "Abilita Timeline locale" enableGlobalTimeline: "Abilita Timeline federata" disablingTimelinesInfo: "Anche se disabiliti queste timeline, gli amministratori e\ @@ -413,7 +410,6 @@ normalPassword: "Password buona" strongPassword: "Password forte" passwordMatched: "Corretta" passwordNotMatched: "Le password non corrispondono." -signinWith: "Accedi con {x}" signinFailed: "Autenticazione non riuscita. Controlla la tua password e nome utente." tapSecurityKey: "Premi la chiave di sicurezza" or: "oppure" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 30f1cbf69..38be75c28 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -286,9 +286,6 @@ dayX: "{day}日" monthX: "{month}月" yearX: "{year}年" pages: "ページ" -integration: "連携" -connectService: "接続する" -disconnectService: "切断する" enableLocalTimeline: "ローカルタイムラインを有効にする" enableGlobalTimeline: "グローバルタイムラインを有効にする" disablingTimelinesInfo: "これらのタイムラインを無効化しても、利便性のため管理者およびモデレーターは引き続き利用することができます。" @@ -392,7 +389,6 @@ normalPassword: "普通のパスワード" strongPassword: "強いパスワード" passwordMatched: "一致しました" passwordNotMatched: "一致していません" -signinWith: "{x}でログイン" signinFailed: "ログインできませんでした。ユーザー名とパスワードを確認してください。" tapSecurityKey: "セキュリティキーにタッチ" or: "もしくは" @@ -1273,13 +1269,3 @@ _deck: list: "リスト" mentions: "あなた宛て" direct: "ダイレクト" -_services: - _discord: - connected: "Discord: @{username}#{discriminator} を、FoundKey: @{mkUsername} に接続しました!" - disconnected: "Discordの連携を解除しました :v:" - _twitter: - connected: "Twitter: @{twitterUserName} を、FoundKey: @{userName} に接続しました!" - disconnected: "Twitterの連携を解除しました :v:" - _github: - connected: "GitHub: @{login} を、FoundKey: @{userName} に接続しました!" - disconnected: "GitHubの連携を解除しました :v:" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index 9aa2b4358..d365def00 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -288,7 +288,6 @@ dayX: "{day}日" monthX: "{month}月" yearX: "{year}年" pages: "ページ" -integration: "連携" enableLocalTimeline: "ローカルタイムラインを使えるようにする" enableGlobalTimeline: "グローバルタイムラインを使えるようにする" disablingTimelinesInfo: "ここらへんのタイムラインを使えんようにしてしもても、管理者とモデレーターは使えるままになってるで、そうやなかったら不便やからな。" @@ -391,7 +390,6 @@ normalPassword: "普通のパスワード" strongPassword: "ええ感じのパスワード" passwordMatched: "よし!一致や!" passwordNotMatched: "一致しとらんで?" -signinWith: "{x}でログイン" or: "それか" language: "言語" uiLanguage: "UIの表示言語" diff --git a/locales/kab-KAB.yml b/locales/kab-KAB.yml index 55a3984b1..dc4f8ba17 100644 --- a/locales/kab-KAB.yml +++ b/locales/kab-KAB.yml @@ -39,7 +39,6 @@ userList: "Tibdarin" securityKey: "Tasarutt n tɣellist" securityKeyName: "Isem n tsarutt" signinRequired: "Ttxil jerred" -signinWith: "Tuqqna s {x}" tapSecurityKey: "Sekcem tasarutt-ik·im n tɣellist" uiLanguage: "Tutlayt n wegrudem" plugins: "Izegrar" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 4f8cac7cb..69a2ad1af 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -315,9 +315,6 @@ dayX: "{day}일" monthX: "{month}월" yearX: "{year}년" pages: "페이지" -integration: "연동" -connectService: "계정 연동" -disconnectService: "계정 연동 해제" enableLocalTimeline: "로컬 타임라인 활성화" enableGlobalTimeline: "글로벌 타임라인 활성화" disablingTimelinesInfo: "특정 타임라인을 비활성화하더라도 관리자 및 모더레이터는 계속 사용할 수 있습니다." @@ -438,7 +435,6 @@ normalPassword: "좋은 비밀번호" strongPassword: "강한 비밀번호" passwordMatched: "일치합니다" passwordNotMatched: "일치하지 않습니다" -signinWith: "{x}로 로그인" signinFailed: "로그인할 수 없습니다. 사용자명과 비밀번호를 확인하여 주십시오." tapSecurityKey: "보안 키를 터치" or: "혹은" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 4345bede6..ae9065097 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -298,9 +298,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Strony" -integration: "Integracja" -connectService: "Połącz" -disconnectService: "Rozłącz" enableLocalTimeline: "Włącz lokalną oś czasu" enableGlobalTimeline: "Włącz globalną oś czasu" disablingTimelinesInfo: "Administratorzy i moderatorzy będą zawsze mieć dostęp do\ @@ -407,7 +404,6 @@ normalPassword: "Dobre hasło" strongPassword: "Silne hasło" passwordMatched: "Pasuje" passwordNotMatched: "Hasła nie pasują do siebie" -signinWith: "Zaloguj się z {x}" signinFailed: "Nie udało się zalogować. Wprowadzona nazwa użytkownika lub hasło są\ \ nieprawidłowe." tapSecurityKey: "Wybierz swój klucz bezpieczeństwa" diff --git a/locales/ro-RO.yml b/locales/ro-RO.yml index 1b343337a..34c2ce7f6 100644 --- a/locales/ro-RO.yml +++ b/locales/ro-RO.yml @@ -311,9 +311,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Pagini" -integration: "Integrare" -connectService: "Conectează" -disconnectService: "Deconectează" enableLocalTimeline: "Activează cronologia locală" enableGlobalTimeline: "Activeaza cronologia globală" disablingTimelinesInfo: "Administratorii și Moderatorii vor avea mereu access la toate\ @@ -420,7 +417,6 @@ normalPassword: "Parolă medie" strongPassword: "Parolă puternică" passwordMatched: "Se potrivește!" passwordNotMatched: "Nu se potrivește" -signinWith: "Autentifică-te cu {x}" signinFailed: "Nu se poate autentifica. Numele de utilizator sau parola introduse\ \ sunt incorecte." tapSecurityKey: "Apasă pe cheia ta de securitate." diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 697bf9f9e..e851d93cb 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -304,9 +304,6 @@ dayX: "{day} день" monthX: "{month} месяц" yearX: "{year} год" pages: "Страницы" -integration: "Интеграция" -connectService: "Подключиться" -disconnectService: "Отключиться" enableLocalTimeline: "Включить локальную ленту" enableGlobalTimeline: "Включить глобальную ленту" disablingTimelinesInfo: "У администраторов и модераторов есть доступ ко всем лентам,\ @@ -415,7 +412,6 @@ normalPassword: "Годный пароль" strongPassword: "Надёжный пароль" passwordMatched: "Совпали" passwordNotMatched: "Не совпадают" -signinWith: "Использовать {x} для входа" signinFailed: "Невозможно войти в систему. Введенное вами имя пользователя или пароль\ \ неверны." tapSecurityKey: "Нажмите на свой электронный ключ" diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml index 1b41b5d5a..ca8b01729 100644 --- a/locales/sk-SK.yml +++ b/locales/sk-SK.yml @@ -305,9 +305,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Stránky" -integration: "Integrácia" -connectService: "Pripojiť" -disconnectService: "Odpojiť" enableLocalTimeline: "Povoliť lokálnu časovú os" enableGlobalTimeline: "Povoliť globálnu časovú os" disablingTimelinesInfo: "Administrátori a moderátori majú vždy prístup ku všetkým\ @@ -414,7 +411,6 @@ normalPassword: "Dobré heslo" strongPassword: "Silné heslo" passwordMatched: "Heslá sú rovnaké" passwordNotMatched: "Heslá nie sú rovnaké" -signinWith: "Prihlásiť sa použitím {x}" signinFailed: "Nedá sa prihlásiť. Skontrolujte prosím meno používateľa a heslo." tapSecurityKey: "Ťuknite na bezpečnostný kľúč" or: "Alebo" diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 8964a01cd..7f06ac629 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -305,9 +305,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Сторінки" -integration: "Інтеграція" -connectService: "Під’єднати" -disconnectService: "Відключитися" enableLocalTimeline: "Увімкнути локальну стрічку" enableGlobalTimeline: "Увімкнути глобальну стрічку" disablingTimelinesInfo: "Адміністратори та модератори завжди мають доступ до всіх\ @@ -414,7 +411,6 @@ normalPassword: "Достатній пароль" strongPassword: "Міцний пароль" passwordMatched: "Все вірно" passwordNotMatched: "Паролі не співпадають" -signinWith: "Увійти за допомогою {x}" signinFailed: "Не вдалося увійти. Введені ім’я користувача або пароль неправильнi." tapSecurityKey: "Торкніться ключа безпеки" or: "або" diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index 7b450e850..59e95a6ae 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -305,9 +305,6 @@ dayX: "{day}" monthX: "{month}" yearX: "{year}" pages: "Trang" -integration: "Tương tác" -connectService: "Kết nối" -disconnectService: "Ngắt kết nối" enableLocalTimeline: "Bật bảng tin máy chủ" enableGlobalTimeline: "Bật bảng tin liên hợp" disablingTimelinesInfo: "Quản trị viên và Kiểm duyệt viên luôn có quyền truy cập mọi\ @@ -415,7 +412,6 @@ normalPassword: "Mật khẩu tạm được" strongPassword: "Mật khẩu mạnh" passwordMatched: "Trùng khớp" passwordNotMatched: "Không trùng khớp" -signinWith: "Đăng nhập bằng {x}" signinFailed: "Không thể đăng nhập. Vui lòng kiểm tra tên người dùng và mật khẩu của\ \ bạn." tapSecurityKey: "Nhấn mã bảo mật của bạn" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index e7f1b58a9..d01be6f06 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -284,9 +284,6 @@ dayX: "{day}日" monthX: "{month}月" yearX: "{year}年" pages: "页面" -integration: "关联" -connectService: "连接" -disconnectService: "断开连接" enableLocalTimeline: "启用本地时间线功能" enableGlobalTimeline: "启用全局时间线" disablingTimelinesInfo: "即使时间线功能被禁用,出于方便,管理员和数据图表也可以继续使用。" @@ -390,7 +387,6 @@ normalPassword: "密码强度:中等" strongPassword: "密码强度:强" passwordMatched: "密码一致" passwordNotMatched: "密码不一致" -signinWith: "以{x}登录" signinFailed: "无法登录,请检查您的用户名和密码是否正确。" tapSecurityKey: "轻触硬件安全密钥" or: "或者" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 01a810bd6..3beedc5b9 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -284,9 +284,6 @@ dayX: "{day}日" monthX: "{month}月" yearX: "{year}年" pages: "頁面" -integration: "整合" -connectService: "己連結" -disconnectService: "己斷開 " enableLocalTimeline: "開啟本地時間軸" enableGlobalTimeline: "啟用公開時間軸" disablingTimelinesInfo: "即使您關閉了時間線功能,管理員和協調人仍可以繼續使用,以方便您。" @@ -390,7 +387,6 @@ normalPassword: "密碼強度普通" strongPassword: "密碼強度高" passwordMatched: "密碼一致" passwordNotMatched: "密碼不一致" -signinWith: "以{x}登錄" signinFailed: "登入失敗。 請檢查使用者名稱和密碼。" tapSecurityKey: "點擊安全密鑰" or: "或者" From b023741f5026289edccdb11cdfab1e6871b238e0 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 6 Dec 2022 23:00:08 +0100 Subject: [PATCH 033/108] server: remove integrations field from user --- .../backend/migration/1670359028055-removeIntegrations.js | 2 ++ packages/backend/src/models/entities/user-profile.ts | 5 ----- packages/backend/src/models/repositories/user.ts | 1 - packages/backend/src/models/schema/user.ts | 4 ---- .../backend/src/server/api/endpoints/admin/show-user.ts | 6 ------ packages/foundkey-js/src/entities.ts | 1 - 6 files changed, 2 insertions(+), 17 deletions(-) diff --git a/packages/backend/migration/1670359028055-removeIntegrations.js b/packages/backend/migration/1670359028055-removeIntegrations.js index fa8d3e4a0..fd0888a6e 100644 --- a/packages/backend/migration/1670359028055-removeIntegrations.js +++ b/packages/backend/migration/1670359028055-removeIntegrations.js @@ -11,9 +11,11 @@ export class removeIntegrations1670359028055 { await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableDiscordIntegration"`); await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "discordClientId"`); await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "discordClientSecret"`); + await queryRunner.query(`ALTER TABLE "user_profile" DROP COLUMN "integrations"`); } async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "user_profile" ADD "integrations" jsonb NOT NULL DEFAULT '{}'`); await queryRunner.query(`ALTER TABLE "meta" ADD "discordClientSecret" character varying(128)`); await queryRunner.query(`ALTER TABLE "meta" ADD "discordClientId" character varying(128)`); await queryRunner.query(`ALTER TABLE "meta" ADD "enableDiscordIntegration" boolean NOT NULL DEFAULT false`); diff --git a/packages/backend/src/models/entities/user-profile.ts b/packages/backend/src/models/entities/user-profile.ts index 58ab00d01..93358e17a 100644 --- a/packages/backend/src/models/entities/user-profile.ts +++ b/packages/backend/src/models/entities/user-profile.ts @@ -167,11 +167,6 @@ export class UserProfile { @JoinColumn() public pinnedPage: Page | null; - @Column('jsonb', { - default: {}, - }) - public integrations: Record; - @Index() @Column('boolean', { default: false, select: false, diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts index 56fd4e218..00dcf7f87 100644 --- a/packages/backend/src/models/repositories/user.ts +++ b/packages/backend/src/models/repositories/user.ts @@ -387,7 +387,6 @@ export const UserRepository = db.getRepository(User).extend({ hasUnreadMessagingMessage: this.getHasUnreadMessagingMessage(user.id), hasUnreadNotification: this.getHasUnreadNotification(user.id), hasPendingReceivedFollowRequest: this.getHasPendingReceivedFollowRequest(user.id), - integrations: profile!.integrations, mutedWords: profile!.mutedWords, mutedInstances: profile!.mutedInstances, mutingNotificationTypes: profile!.mutingNotificationTypes, diff --git a/packages/backend/src/models/schema/user.ts b/packages/backend/src/models/schema/user.ts index dae8f692c..fcb61f918 100644 --- a/packages/backend/src/models/schema/user.ts +++ b/packages/backend/src/models/schema/user.ts @@ -352,10 +352,6 @@ export const packedMeDetailedOnlySchema = { type: 'boolean', nullable: false, optional: false, }, - integrations: { - type: 'object', - nullable: true, optional: false, - }, mutedWords: { type: 'array', nullable: false, optional: false, diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts index bc9c193f8..d7cf37ea3 100644 --- a/packages/backend/src/server/api/endpoints/admin/show-user.ts +++ b/packages/backend/src/server/api/endpoints/admin/show-user.ts @@ -45,11 +45,6 @@ export default define(meta, paramDef, async (ps, me) => { }; } - const maskedKeys = ['accessToken', 'accessTokenSecret', 'refreshToken']; - Object.keys(profile.integrations).forEach(integration => { - maskedKeys.forEach(key => profile.integrations[integration][key] = ''); - }); - const signins = await Signins.findBy({ userId: user.id }); return { @@ -61,7 +56,6 @@ export default define(meta, paramDef, async (ps, me) => { carefulBot: profile.carefulBot, injectFeaturedNote: profile.injectFeaturedNote, receiveAnnouncementEmail: profile.receiveAnnouncementEmail, - integrations: profile.integrations, mutedWords: profile.mutedWords, mutedInstances: profile.mutedInstances, mutingNotificationTypes: profile.mutingNotificationTypes, diff --git a/packages/foundkey-js/src/entities.ts b/packages/foundkey-js/src/entities.ts index 2fd05c1cf..236b2a8a3 100644 --- a/packages/foundkey-js/src/entities.ts +++ b/packages/foundkey-js/src/entities.ts @@ -98,7 +98,6 @@ export type MeDetailed = UserDetailed & { hasUnreadSpecifiedNotes: boolean; hideOnlineStatus: boolean; injectFeaturedNote: boolean; - integrations: Record; isDeleted: boolean; isExplorable: boolean; mutedWords: string[][]; From 96c37445554ad270d4fc58214f296e85c5fceb04 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 6 Dec 2022 23:00:32 +0100 Subject: [PATCH 034/108] client: remove integration settings menu entry --- packages/client/src/pages/settings/index.vue | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/client/src/pages/settings/index.vue b/packages/client/src/pages/settings/index.vue index 280f5d210..4810d80c9 100644 --- a/packages/client/src/pages/settings/index.vue +++ b/packages/client/src/pages/settings/index.vue @@ -89,11 +89,6 @@ const menuDef = computed(() => [{ text: i18n.ts.email, to: '/settings/email', active: props.initialPage === 'email', - }, { - icon: 'fas fa-share-alt', - text: i18n.ts.integration, - to: '/settings/integration', - active: props.initialPage === 'integration', }, { icon: 'fas fa-lock', text: i18n.ts.security, From 1aa3898db54cd9a7589943871a910771538280ac Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 6 Dec 2022 23:12:45 +0100 Subject: [PATCH 035/108] server: remove unused import --- packages/backend/src/remote/activitypub/models/person.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index 503547972..c6eb92b4a 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -25,7 +25,7 @@ import { publishInternalEvent } from '@/services/stream.js'; import { db } from '@/db/postgre.js'; import { apLogger } from '../logger.js'; import { fromHtml } from '@/mfm/from-html.js'; -import { isCollectionOrOrderedCollection, isCollection, IActor, getApId, getOneApHrefNullable, IObject, isPropertyValue, IApPropertyValue, getApType, isActor } from '../type.js'; +import { isCollectionOrOrderedCollection, isCollection, IActor, getApId, getOneApHrefNullable, IObject, isPropertyValue, getApType, isActor } from '../type.js'; import Resolver from '../resolver.js'; import { extractApHashtags } from './tag.js'; import { resolveNote, extractEmojis } from './note.js'; From d3f1ad9a88f7f13805a642414948e1fd898267b6 Mon Sep 17 00:00:00 2001 From: Andreas Nedbal Date: Tue, 6 Dec 2022 23:18:27 +0100 Subject: [PATCH 036/108] chore: remove unused packages --- packages/backend/package.json | 2 -- packages/client/package.json | 2 -- yarn.lock | 29 ----------------------------- 3 files changed, 33 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index dc18c5e30..4dd134b32 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -29,7 +29,6 @@ "ajv": "8.11.0", "archiver": "5.3.1", "autobind-decorator": "2.4.0", - "autwh": "0.1.0", "aws-sdk": "2.1165.0", "bcryptjs": "2.4.3", "blurhash": "1.1.5", @@ -146,7 +145,6 @@ "@types/node": "18.7.16", "@types/node-fetch": "3.0.3", "@types/nodemailer": "6.4.5", - "@types/oauth": "^0.9.1", "@types/pg": "^8.6.5", "@types/pug": "2.0.6", "@types/punycode": "2.1.0", diff --git a/packages/client/package.json b/packages/client/package.json index d672895ce..bc904ffbe 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -18,7 +18,6 @@ "abort-controller": "3.0.0", "autobind-decorator": "2.4.0", "autosize": "5.0.1", - "autwh": "0.1.0", "blurhash": "1.1.5", "broadcast-channel": "4.13.0", "browser-image-resizer": "2.4.1", @@ -86,7 +85,6 @@ "@types/katex": "0.14.0", "@types/matter-js": "0.17.7", "@types/mocha": "9.1.1", - "@types/oauth": "0.9.1", "@types/punycode": "2.1.0", "@types/qrcode": "1.5.0", "@types/seedrandom": "3.0.2", diff --git a/yarn.lock b/yarn.lock index 7432ff230..7ddb9e66b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2216,15 +2216,6 @@ __metadata: languageName: node linkType: hard -"@types/oauth@npm:0.9.1, @types/oauth@npm:^0.9.1": - version: 0.9.1 - resolution: "@types/oauth@npm:0.9.1" - dependencies: - "@types/node": "*" - checksum: 5c079611b455eff58fba6358e028b191a1e65475600f8ed8d98c1696fedcfb0290aa6c6a19cf50f21a9e2d816ecb43a19f910900d91f8ba3727e33c48f97d7f3 - languageName: node - linkType: hard - "@types/parse5@npm:*": version: 7.0.0 resolution: "@types/parse5@npm:7.0.0" @@ -3474,15 +3465,6 @@ __metadata: languageName: node linkType: hard -"autwh@npm:0.1.0": - version: 0.1.0 - resolution: "autwh@npm:0.1.0" - dependencies: - oauth: 0.9.15 - checksum: 5ca904d43421e7475de29adfda65ca769105cbf597c9c43fef934f20b0daa331621157cdf34513eae5f492e1b4fc6443f37438da08bf2ba1c4e3e7d6d3f3f738 - languageName: node - linkType: hard - "aws-sdk@npm:2.1165.0": version: 2.1165.0 resolution: "aws-sdk@npm:2.1165.0" @@ -3675,7 +3657,6 @@ __metadata: "@types/node": 18.7.16 "@types/node-fetch": 3.0.3 "@types/nodemailer": 6.4.5 - "@types/oauth": ^0.9.1 "@types/pg": ^8.6.5 "@types/pug": 2.0.6 "@types/punycode": 2.1.0 @@ -3702,7 +3683,6 @@ __metadata: ajv: 8.11.0 archiver: 5.3.1 autobind-decorator: 2.4.0 - autwh: 0.1.0 aws-sdk: 2.1165.0 bcryptjs: 2.4.3 blurhash: 1.1.5 @@ -4704,7 +4684,6 @@ __metadata: "@types/katex": 0.14.0 "@types/matter-js": 0.17.7 "@types/mocha": 9.1.1 - "@types/oauth": 0.9.1 "@types/punycode": 2.1.0 "@types/qrcode": 1.5.0 "@types/seedrandom": 3.0.2 @@ -4719,7 +4698,6 @@ __metadata: abort-controller: 3.0.0 autobind-decorator: 2.4.0 autosize: 5.0.1 - autwh: 0.1.0 blurhash: 1.1.5 broadcast-channel: 4.13.0 browser-image-resizer: 2.4.1 @@ -12623,13 +12601,6 @@ __metadata: languageName: node linkType: hard -"oauth@npm:0.9.15": - version: 0.9.15 - resolution: "oauth@npm:0.9.15" - checksum: 957c0d8d85300398dcb0e293953650c0fc3facc795bee8228238414f19f59cef5fd4ee8d17a972c142924c10c5f6ec50ef80f77f4a6cc6e3c98f9d22c027801c - languageName: node - linkType: hard - "object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" From 0f3f42eb395300399b1e60f511ba596a2461ac39 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Wed, 7 Dec 2022 18:03:29 +0100 Subject: [PATCH 037/108] remove rndstr dependency This dependency was unused in the client. The use of it in the server can be replaced entirely by the secureRndstr function, with some slight modifications. That function could probably be refactored a bit more as well. --- packages/backend/package.json | 1 - packages/backend/src/misc/secure-rndstr.ts | 8 ++++-- .../src/server/api/common/inject-featured.ts | 4 +-- .../server/api/endpoints/admin/emoji/add.ts | 3 +-- .../src/server/api/endpoints/admin/invite.ts | 8 +++--- .../api/endpoints/admin/reset-password.ts | 4 +-- .../server/api/endpoints/i/update-email.ts | 4 +-- .../api/endpoints/request-reset-password.ts | 4 +-- .../backend/src/server/api/private/signup.ts | 4 +-- packages/client/package.json | 1 - yarn.lock | 26 ------------------- 11 files changed, 20 insertions(+), 47 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 4dd134b32..6fa587750 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -91,7 +91,6 @@ "reflect-metadata": "0.1.13", "rename": "1.0.4", "require-all": "3.0.0", - "rndstr": "1.0.0", "rss-parser": "3.12.0", "sanitize-html": "2.7.0", "semver": "7.3.7", diff --git a/packages/backend/src/misc/secure-rndstr.ts b/packages/backend/src/misc/secure-rndstr.ts index 8d4fcb1ba..1da3c53ef 100644 --- a/packages/backend/src/misc/secure-rndstr.ts +++ b/packages/backend/src/misc/secure-rndstr.ts @@ -3,8 +3,7 @@ import * as crypto from 'node:crypto'; const L_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz'; const LU_CHARS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; -export function secureRndstr(length = 32, useLU = true): string { - const chars = useLU ? LU_CHARS : L_CHARS; +export function secureRndstrCustom(length = 32, chars: string): string { const chars_len = chars.length; let str = ''; @@ -19,3 +18,8 @@ export function secureRndstr(length = 32, useLU = true): string { return str; } + +export function secureRndstr(length = 32, useLU = true): string { + const chars = useLU ? LU_CHARS : L_CHARS; + return secureRndstrCustom(length, chars); +} diff --git a/packages/backend/src/server/api/common/inject-featured.ts b/packages/backend/src/server/api/common/inject-featured.ts index f79c57cbf..13bf156c1 100644 --- a/packages/backend/src/server/api/common/inject-featured.ts +++ b/packages/backend/src/server/api/common/inject-featured.ts @@ -1,7 +1,7 @@ -import rndstr from 'rndstr'; import { DAY } from '@/const.js'; import { Note } from '@/models/entities/note.js'; import { User } from '@/models/entities/user.js'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; import { Notes, UserProfiles, NoteReactions } from '@/models/index.js'; import { generateMutedUserQuery } from './generate-muted-user-query.js'; import { generateBlockedUserQuery } from './generate-block-query.js'; @@ -50,7 +50,7 @@ export async function injectFeatured(timeline: Note[], user?: User | null) { // Pick random one const featured = notes[Math.floor(Math.random() * notes.length)]; - (featured as any)._featuredId_ = rndstr('a-z0-9', 8); + (featured as any)._featuredId_ = secureRndstr(8); // Inject featured timeline.splice(3, 0, featured); diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts index ad5b9896c..a4871da27 100644 --- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts +++ b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts @@ -1,4 +1,3 @@ -import rndstr from 'rndstr'; import { publishBroadcastStream } from '@/services/stream.js'; import { db } from '@/db/postgre.js'; import { Emojis, DriveFiles } from '@/models/index.js'; @@ -30,7 +29,7 @@ export default define(meta, paramDef, async (ps, me) => { if (file == null) throw new ApiError('NO_SUCH_FILE'); - const name = file.name.split('.')[0].match(/^[a-z0-9_]+$/) ? file.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`; + const name = file.name.split('.')[0].match(/^[a-z0-9_]+$/) ? file.name.split('.')[0] : `_${genId()}_`; const emoji = await Emojis.insert({ id: genId(), diff --git a/packages/backend/src/server/api/endpoints/admin/invite.ts b/packages/backend/src/server/api/endpoints/admin/invite.ts index a7b2dac4d..38ec85e51 100644 --- a/packages/backend/src/server/api/endpoints/admin/invite.ts +++ b/packages/backend/src/server/api/endpoints/admin/invite.ts @@ -1,6 +1,6 @@ -import rndstr from 'rndstr'; import { RegistrationTickets } from '@/models/index.js'; import { genId } from '@/misc/gen-id.js'; +import { secureRndstrCustom } from '@/misc/secure-rndstr.js'; import define from '../../define.js'; export const meta = { @@ -32,10 +32,8 @@ export const paramDef = { // eslint-disable-next-line import/no-default-export export default define(meta, paramDef, async () => { - const code = rndstr({ - length: 8, - chars: '2-9A-HJ-NP-Z', // [0-9A-Z] w/o [01IO] (32 patterns) - }); + // omit visually ambiguous zero and letter O as well as one and letter I + const code = secureRndstrCustom(8, '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'); await RegistrationTickets.insert({ id: genId(), diff --git a/packages/backend/src/server/api/endpoints/admin/reset-password.ts b/packages/backend/src/server/api/endpoints/admin/reset-password.ts index d0a98ff5b..97d6f51d4 100644 --- a/packages/backend/src/server/api/endpoints/admin/reset-password.ts +++ b/packages/backend/src/server/api/endpoints/admin/reset-password.ts @@ -1,5 +1,5 @@ import bcrypt from 'bcryptjs'; -import rndstr from 'rndstr'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; import { Users, UserProfiles } from '@/models/index.js'; import define from '../../define.js'; @@ -43,7 +43,7 @@ export default define(meta, paramDef, async (ps) => { throw new Error('cannot reset password of admin'); } - const passwd = rndstr('a-zA-Z0-9', 8); + const passwd = secureRndstr(8, true); // Generate hash of password const hash = bcrypt.hashSync(passwd); diff --git a/packages/backend/src/server/api/endpoints/i/update-email.ts b/packages/backend/src/server/api/endpoints/i/update-email.ts index cb3d6356a..057ad5cf3 100644 --- a/packages/backend/src/server/api/endpoints/i/update-email.ts +++ b/packages/backend/src/server/api/endpoints/i/update-email.ts @@ -1,7 +1,7 @@ -import rndstr from 'rndstr'; import bcrypt from 'bcryptjs'; import { publishMainStream } from '@/services/stream.js'; import config from '@/config/index.js'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; import { Users, UserProfiles } from '@/models/index.js'; import { sendEmail } from '@/services/send-email.js'; import { validateEmailForAccount } from '@/services/validate-email-for-account.js'; @@ -62,7 +62,7 @@ export default define(meta, paramDef, async (ps, user) => { publishMainStream(user.id, 'meUpdated', iObj); if (ps.email != null) { - const code = rndstr('a-z0-9', 16); + const code = secureRndstr(16); await UserProfiles.update(user.id, { emailVerifyCode: code, diff --git a/packages/backend/src/server/api/endpoints/request-reset-password.ts b/packages/backend/src/server/api/endpoints/request-reset-password.ts index 4ca4703e9..e97d9c4b2 100644 --- a/packages/backend/src/server/api/endpoints/request-reset-password.ts +++ b/packages/backend/src/server/api/endpoints/request-reset-password.ts @@ -1,9 +1,9 @@ -import rndstr from 'rndstr'; import { IsNull } from 'typeorm'; import config from '@/config/index.js'; import { Users, UserProfiles, PasswordResetRequests } from '@/models/index.js'; import { sendEmail } from '@/services/send-email.js'; import { genId } from '@/misc/gen-id.js'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; import { DAY } from '@/const.js'; import define from '../define.js'; @@ -53,7 +53,7 @@ export default define(meta, paramDef, async (ps) => { return; } - const token = rndstr('a-z0-9', 64); + const token = secureRndstr(64); await PasswordResetRequests.insert({ id: genId(), diff --git a/packages/backend/src/server/api/private/signup.ts b/packages/backend/src/server/api/private/signup.ts index bb2a11437..e20fb9abb 100644 --- a/packages/backend/src/server/api/private/signup.ts +++ b/packages/backend/src/server/api/private/signup.ts @@ -1,11 +1,11 @@ import Koa from 'koa'; -import rndstr from 'rndstr'; import bcrypt from 'bcryptjs'; import { fetchMeta } from '@/misc/fetch-meta.js'; import { verifyHcaptcha, verifyRecaptcha } from '@/misc/captcha.js'; import { Users, RegistrationTickets, UserPendings } from '@/models/index.js'; import config from '@/config/index.js'; import { sendEmail } from '@/services/send-email.js'; +import { secureRndstr } from '@/misc/secure-rndstr.js'; import { genId } from '@/misc/gen-id.js'; import { validateEmailForAccount } from '@/services/validate-email-for-account.js'; import { signup } from '../common/signup.js'; @@ -69,7 +69,7 @@ export default async (ctx: Koa.Context) => { } if (instance.emailRequiredForSignup) { - const code = rndstr('a-z0-9', 16); + const code = secureRndstr(16); // Generate hash of password const salt = await bcrypt.genSalt(8); diff --git a/packages/client/package.json b/packages/client/package.json index bc904ffbe..c83497529 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -50,7 +50,6 @@ "punycode": "2.1.1", "qrcode": "1.5.1", "reflect-metadata": "0.1.13", - "rndstr": "1.0.0", "rollup": "2.75.7", "sass": "1.53.0", "seedrandom": "3.0.5", diff --git a/yarn.lock b/yarn.lock index 7ddb9e66b..1819dee80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3750,7 +3750,6 @@ __metadata: reflect-metadata: 0.1.13 rename: 1.0.4 require-all: 3.0.0 - rndstr: 1.0.0 rss-parser: 3.12.0 sanitize-html: 2.7.0 semver: 7.3.7 @@ -4735,7 +4734,6 @@ __metadata: punycode: 2.1.1 qrcode: 1.5.1 reflect-metadata: 0.1.13 - rndstr: 1.0.0 rollup: 2.75.7 sass: 1.53.0 seedrandom: 3.0.5 @@ -14292,13 +14290,6 @@ __metadata: languageName: node linkType: hard -"rangestr@npm:0.0.1": - version: 0.0.1 - resolution: "rangestr@npm:0.0.1" - checksum: d7e3233f43a196a513f0f6c6a8a0a46b3c0e5fff97ad4d0c45031ea7494a3785d5db36d36231609b416acddaf5fe464e2c74fcc7a8f4032af83e05af23c33700 - languageName: node - linkType: hard - "ratelimiter@npm:3.4.1": version: 3.4.1 resolution: "ratelimiter@npm:3.4.1" @@ -14954,16 +14945,6 @@ __metadata: languageName: node linkType: hard -"rndstr@npm:1.0.0": - version: 1.0.0 - resolution: "rndstr@npm:1.0.0" - dependencies: - rangestr: 0.0.1 - seedrandom: 2.4.2 - checksum: 4eb485a72bbcdfdd8017888122eaa2fe391d92f5a426558ae523f485d7d0fee8a0122ed513955225aab9a034d6eb694d8fb034c612de0bfadf5f4734d592789d - languageName: node - linkType: hard - "rollup@npm:2.75.7": version: 2.75.7 resolution: "rollup@npm:2.75.7" @@ -15150,13 +15131,6 @@ __metadata: languageName: node linkType: hard -"seedrandom@npm:2.4.2": - version: 2.4.2 - resolution: "seedrandom@npm:2.4.2" - checksum: 09b4a2883e667601338964f86c000839f64ca8f811c41b4b425a03eabc5c4d243e09b5d15c29c3441cd61a384a316b02d341dbfaf3b0097b5973aa12544f9435 - languageName: node - linkType: hard - "seedrandom@npm:3.0.5": version: 3.0.5 resolution: "seedrandom@npm:3.0.5" From 18664dbca3b62d2ad0869724308e2ae9f6afd45b Mon Sep 17 00:00:00 2001 From: Johann150 Date: Wed, 7 Dec 2022 18:28:47 +0100 Subject: [PATCH 038/108] server: add missing paren How did this not break yet? --- packages/backend/src/mfm/from-html.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/mfm/from-html.ts b/packages/backend/src/mfm/from-html.ts index 1c8fcc077..0ec5b962e 100644 --- a/packages/backend/src/mfm/from-html.ts +++ b/packages/backend/src/mfm/from-html.ts @@ -72,7 +72,7 @@ export function fromHtml(html: string, quoteUri?: string | null): string { const href = getAttr(node, 'href'); // hashtags - if (txt.startsWith('#') && href && (attrHas(node, 'rel', 'tag') || attrHas(node, 'class', 'hashtag')) { + if (txt.startsWith('#') && href && (attrHas(node, 'rel', 'tag') || attrHas(node, 'class', 'hashtag'))) { text += txt; // mentions } else if (txt.startsWith('@') && !attrHas(node, 'rel', 'me')) { From b66f7550abca12fa22ebc3b0071fb2b9eb0f3ff6 Mon Sep 17 00:00:00 2001 From: Francis Dinh Date: Wed, 7 Dec 2022 13:39:21 -0500 Subject: [PATCH 039/108] server: auto-fix lints --- packages/backend/src/boot/master.ts | 2 +- packages/backend/src/misc/skipped-instances.ts | 2 +- packages/backend/src/models/entities/auth-session.ts | 2 +- packages/backend/src/remote/activitypub/deliver-manager.ts | 4 ++-- packages/backend/src/remote/activitypub/misc/auth-user.ts | 2 +- packages/backend/src/remote/activitypub/models/person.ts | 2 +- packages/backend/src/server/api/common/oauth.ts | 3 +-- .../backend/src/server/api/endpoints/auth/session/generate.ts | 2 +- .../server/api/endpoints/users/search-by-username-and-host.ts | 2 +- packages/backend/src/server/api/openapi/gen-spec.ts | 4 ++-- packages/backend/src/services/note/polls/vote.ts | 2 +- packages/backend/src/services/user-cache.ts | 2 +- 12 files changed, 14 insertions(+), 15 deletions(-) diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index b4d95346f..6b1fce48c 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -153,7 +153,7 @@ async function spawnWorkers(clusterLimits: Required): P bootLogger.info(`Starting ${total} workers...`); await Promise.all(workers.map(mode => spawnWorker(mode))); - bootLogger.succ(`All workers started`); + bootLogger.succ('All workers started'); } function spawnWorker(mode: 'web' | 'queue'): Promise { diff --git a/packages/backend/src/misc/skipped-instances.ts b/packages/backend/src/misc/skipped-instances.ts index 37587c52e..efd1d588d 100644 --- a/packages/backend/src/misc/skipped-instances.ts +++ b/packages/backend/src/misc/skipped-instances.ts @@ -27,7 +27,7 @@ export async function skippedInstances(hosts: Array): Promise< return skipped.concat( await db.query( - `SELECT host FROM instance WHERE ("isSuspended" OR "latestStatus" = 410 OR "lastCommunicatedAt" < $1::date) AND host = ANY(string_to_array($2, ','))`, + 'SELECT host FROM instance WHERE ("isSuspended" OR "latestStatus" = 410 OR "lastCommunicatedAt" < $1::date) AND host = ANY(string_to_array($2, \',\'))', [ deadTime.toISOString(), // don't check hosts again that we already know are suspended diff --git a/packages/backend/src/models/entities/auth-session.ts b/packages/backend/src/models/entities/auth-session.ts index 98031f2de..8e3057dc6 100644 --- a/packages/backend/src/models/entities/auth-session.ts +++ b/packages/backend/src/models/entities/auth-session.ts @@ -45,5 +45,5 @@ export class AuthSession { nullable: true, comment: 'PKCE code_challenge value, if provided (OAuth only)', }) - pkceChallenge: string | null; + pkceChallenge: string | null; } diff --git a/packages/backend/src/remote/activitypub/deliver-manager.ts b/packages/backend/src/remote/activitypub/deliver-manager.ts index c706968df..bc86e5e58 100644 --- a/packages/backend/src/remote/activitypub/deliver-manager.ts +++ b/packages/backend/src/remote/activitypub/deliver-manager.ts @@ -147,8 +147,8 @@ export default class DeliverManager { // get (unique) list of hosts Array.from(new Set( Array.from(inboxes) - .map(inbox => new URL(inbox).host) - )) + .map(inbox => new URL(inbox).host), + )), ); // deliver diff --git a/packages/backend/src/remote/activitypub/misc/auth-user.ts b/packages/backend/src/remote/activitypub/misc/auth-user.ts index d8a7202f2..4705bb791 100644 --- a/packages/backend/src/remote/activitypub/misc/auth-user.ts +++ b/packages/backend/src/remote/activitypub/misc/auth-user.ts @@ -23,7 +23,7 @@ function authUserFromApId(uri: string): Promise { return uriPersonCache.fetch(uri) .then(async user => { if (!user) return null; - let key = await publicKeyByUserIdCache.fetch(user.id); + const key = await publicKeyByUserIdCache.fetch(user.id); if (!key) return null; return { user, key }; }); diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts index c6eb92b4a..977cfb0ff 100644 --- a/packages/backend/src/remote/activitypub/models/person.ts +++ b/packages/backend/src/remote/activitypub/models/person.ts @@ -23,8 +23,8 @@ import { StatusError } from '@/misc/fetch.js'; import { uriPersonCache } from '@/services/user-cache.js'; import { publishInternalEvent } from '@/services/stream.js'; import { db } from '@/db/postgre.js'; -import { apLogger } from '../logger.js'; import { fromHtml } from '@/mfm/from-html.js'; +import { apLogger } from '../logger.js'; import { isCollectionOrOrderedCollection, isCollection, IActor, getApId, getOneApHrefNullable, IObject, isPropertyValue, getApType, isActor } from '../type.js'; import Resolver from '../resolver.js'; import { extractApHashtags } from './tag.js'; diff --git a/packages/backend/src/server/api/common/oauth.ts b/packages/backend/src/server/api/common/oauth.ts index c09712e9b..894842d40 100644 --- a/packages/backend/src/server/api/common/oauth.ts +++ b/packages/backend/src/server/api/common/oauth.ts @@ -127,5 +127,4 @@ export async function oauth(ctx: Koa.Context): void { token_type: 'bearer', scope: session.accessToken.permission.join(' '), }; - -}; +} diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts index fe1286c03..8fb133bdf 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/generate.ts @@ -57,7 +57,7 @@ export const paramDef = { minLength: 1, }, }, - required: ['clientId'] + required: ['clientId'], }, { properties: { appSecret: { type: 'string' }, diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts index 84096eac0..cbde7ef79 100644 --- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts +++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts @@ -1,5 +1,5 @@ -import { MONTH } from '@/const.js'; import { Brackets } from 'typeorm'; +import { MONTH } from '@/const.js'; import { Followings, Users } from '@/models/index.js'; import { User } from '@/models/entities/user.js'; import define from '../../define.js'; diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index a7f5d5cc9..fbb8d3163 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -1,10 +1,10 @@ import config from '@/config/index.js'; +import { kinds } from '@/misc/api-permissions.js'; +import { I18n } from '@/misc/i18n.js'; import { errors as errorDefinitions } from '../error.js'; import endpoints from '../endpoints.js'; import { schemas, convertSchemaToOpenApiSchema } from './schemas.js'; import { httpCodes } from './http-codes.js'; -import { kinds } from '@/misc/api-permissions.js'; -import { I18n } from '@/misc/i18n.js'; const i18n = new I18n('en-US'); diff --git a/packages/backend/src/services/note/polls/vote.ts b/packages/backend/src/services/note/polls/vote.ts index 5e27159e8..6e22af41f 100644 --- a/packages/backend/src/services/note/polls/vote.ts +++ b/packages/backend/src/services/note/polls/vote.ts @@ -68,7 +68,7 @@ export async function vote(user: CacheableUser, note: Note, choice: number): Pro createNotification(note.userId, 'pollVote', { notifierId: user.id, noteId: note.id, - choice: choice, + choice, }); } diff --git a/packages/backend/src/services/user-cache.ts b/packages/backend/src/services/user-cache.ts index f7f58dba5..d30b76a24 100644 --- a/packages/backend/src/services/user-cache.ts +++ b/packages/backend/src/services/user-cache.ts @@ -29,7 +29,7 @@ subscriber.on('message', async (_, data) => { const user = await Users.findOneByOrFail({ id: body.id }); userByIdCache.set(user.id, user); for (const [k, v] of uriPersonCache.cache.entries()) { - if (v.value?.id === user.id) { + if (v.value.id === user.id) { uriPersonCache.set(k, user); } } From 501cf834c86c0f40969d58ba13ab122664c96e67 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Wed, 7 Dec 2022 21:55:39 +0100 Subject: [PATCH 040/108] client: fix issue of search only working once closes https://akkoma.dev/FoundKeyGang/FoundKey/issues/274 Changelog: Fixed --- packages/client/src/pages/search.vue | 67 +++++++++++++++------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/packages/client/src/pages/search.vue b/packages/client/src/pages/search.vue index e161e728a..d3afdd9b4 100644 --- a/packages/client/src/pages/search.vue +++ b/packages/client/src/pages/search.vue @@ -55,7 +55,7 @@ - - From 0e3321c106d6770f77e4a29b91ba4287b1b4f1c6 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sat, 17 Dec 2022 23:32:25 +0100 Subject: [PATCH 104/108] client: unify import names of MkButton component --- packages/client/src/pages/admin/bot-protection.vue | 4 ++-- packages/client/src/pages/admin/instance-block.vue | 4 ++-- packages/client/src/pages/admin/proxy-account.vue | 4 ++-- packages/client/src/pages/admin/security.vue | 4 ++-- packages/client/src/pages/gallery/edit.vue | 10 +++++----- packages/client/src/pages/reset-password.vue | 4 ++-- packages/client/src/pages/settings/accounts.vue | 4 ++-- packages/client/src/pages/settings/api.vue | 4 ++-- packages/client/src/pages/settings/delete-account.vue | 6 +++--- packages/client/src/pages/settings/menu.vue | 4 ++-- packages/client/src/pages/settings/notifications.vue | 1 - packages/client/src/pages/settings/plugin.install.vue | 4 ++-- packages/client/src/pages/settings/reaction.vue | 6 +++--- packages/client/src/pages/settings/security.vue | 6 +++--- packages/client/src/pages/settings/sounds.vue | 4 ++-- packages/client/src/pages/settings/theme.install.vue | 6 +++--- packages/client/src/pages/settings/theme.manage.vue | 4 ++-- packages/client/src/pages/settings/theme.vue | 6 +++--- packages/client/src/pages/settings/webhook.edit.vue | 6 +++--- packages/client/src/pages/settings/webhook.new.vue | 4 ++-- packages/client/src/pages/theme-editor.vue | 4 ++-- packages/client/src/pages/user-info.vue | 8 ++++---- 22 files changed, 53 insertions(+), 54 deletions(-) diff --git a/packages/client/src/pages/admin/bot-protection.vue b/packages/client/src/pages/admin/bot-protection.vue index cf2cdea92..05d60511b 100644 --- a/packages/client/src/pages/admin/bot-protection.vue +++ b/packages/client/src/pages/admin/bot-protection.vue @@ -37,7 +37,7 @@ - {{ i18n.ts.save }} + {{ i18n.ts.save }}
@@ -47,7 +47,7 @@ import { defineAsyncComponent } from 'vue'; import FormRadios from '@/components/form/radios.vue'; import FormInput from '@/components/form/input.vue'; -import FormButton from '@/components/ui/button.vue'; +import MkButton from '@/components/ui/button.vue'; import FormSuspense from '@/components/form/suspense.vue'; import FormSlot from '@/components/form/slot.vue'; import * as os from '@/os'; diff --git a/packages/client/src/pages/admin/instance-block.vue b/packages/client/src/pages/admin/instance-block.vue index 08d74c3e5..c6d0f584d 100644 --- a/packages/client/src/pages/admin/instance-block.vue +++ b/packages/client/src/pages/admin/instance-block.vue @@ -8,14 +8,14 @@ - {{ i18n.ts.save }} + {{ i18n.ts.save }}