From 98e42ec6ffd245f522bc1cbceda0d3f84d3330b5 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 14 May 2022 15:00:15 +0900 Subject: enhance: Display TOTP Register URL Close #7261 Co-Authored-By: tamaina --- packages/backend/src/server/api/endpoints/i/2fa/register.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'packages/backend/src/server/api/endpoints') diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register.ts b/packages/backend/src/server/api/endpoints/i/2fa/register.ts index d5e1b19e54..33f5717728 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/register.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/register.ts @@ -2,8 +2,8 @@ import bcrypt from 'bcryptjs'; import * as speakeasy from 'speakeasy'; import * as QRCode from 'qrcode'; import config from '@/config/index.js'; -import define from '../../../define.js'; import { UserProfiles } from '@/models/index.js'; +import define from '../../../define.js'; export const meta = { requireCredential: true, @@ -40,15 +40,17 @@ export default define(meta, paramDef, async (ps, user) => { }); // Get the data URL of the authenticator URL - const dataUrl = await QRCode.toDataURL(speakeasy.otpauthURL({ + const url = speakeasy.otpauthURL({ secret: secret.base32, encoding: 'base32', label: user.username, issuer: config.host, - })); + }); + const dataUrl = await QRCode.toDataURL(url); return { qr: dataUrl, + url, secret: secret.base32, label: user.username, issuer: config.host, -- cgit v1.2.3-freya From 4b872856c2c79ea4e604af481cd2c78487993d88 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sat, 14 May 2022 08:09:10 +0200 Subject: fix: keep file order (#8659) --- packages/backend/src/server/api/endpoints/notes/create.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'packages/backend/src/server/api/endpoints') diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index 40a3ba73ca..ff62841a0c 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -172,10 +172,14 @@ export default define(meta, paramDef, async (ps, user) => { let files: DriveFile[] = []; const fileIds = ps.fileIds != null ? ps.fileIds : ps.mediaIds != null ? ps.mediaIds : null; if (fileIds != null) { - files = await DriveFiles.findBy({ - userId: user.id, - id: In(fileIds), - }); + files = await DriveFiles.createQueryBuilder('file') + .where('file.userId = :userId AND file.id IN (:...fileIds)', { + userId: user.id, + fileIds, + }) + .orderBy('array_position(ARRAY[:...fileIds], "id")') + .setParameters({ fileIds }) + .getMany(); } let renote: Note | null = null; -- cgit v1.2.3-freya From b2a5076d14e84fc427e9ab59ae373b04ddfbf40c Mon Sep 17 00:00:00 2001 From: tamaina Date: Sat, 14 May 2022 15:24:44 +0900 Subject: fix: ユーザー検索で、クエリがusernameの条件を満たす場合はusernameもLIKE検索するように (#8644) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #8643 * 部分一致にする --- packages/backend/src/server/api/endpoints/users/search.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'packages/backend/src/server/api/endpoints') diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts index a72a58a843..f93d4f718b 100644 --- a/packages/backend/src/server/api/endpoints/users/search.ts +++ b/packages/backend/src/server/api/endpoints/users/search.ts @@ -61,7 +61,14 @@ export default define(meta, paramDef, async (ps, me) => { .getMany(); } else { const nameQuery = Users.createQueryBuilder('user') - .where('user.name ILIKE :query', { query: '%' + ps.query + '%' }) + .where(new Brackets(qb => { + qb.where('user.name ILIKE :query', { query: '%' + ps.query + '%' }); + + // Also search username if it qualifies as username + if (Users.validateLocalUsername(ps.query)) { + qb.orWhere('user.usernameLower LIKE :username', { username: '%' + ps.query.toLowerCase() + '%' }); + } + })) .andWhere(new Brackets(qb => { qb .where('user.updatedAt IS NULL') .orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold }); -- cgit v1.2.3-freya From 037ca92275bd8917eb7bf6f62f7613adc2bbaf36 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sun, 15 May 2022 11:32:00 +0200 Subject: fix: postgres type error Fix a bug introduced in #8659. Solution was already tested there. --- packages/backend/src/server/api/endpoints/notes/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/backend/src/server/api/endpoints') diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts index ff62841a0c..955f53bbc1 100644 --- a/packages/backend/src/server/api/endpoints/notes/create.ts +++ b/packages/backend/src/server/api/endpoints/notes/create.ts @@ -177,7 +177,7 @@ export default define(meta, paramDef, async (ps, user) => { userId: user.id, fileIds, }) - .orderBy('array_position(ARRAY[:...fileIds], "id")') + .orderBy('array_position(ARRAY[:...fileIds], "id"::text)') .setParameters({ fileIds }) .getMany(); } -- cgit v1.2.3-freya From aaf5bb62abd6c1daefc675a7aa7eebfac561fb3a Mon Sep 17 00:00:00 2001 From: Johann150 Date: Thu, 19 May 2022 09:54:45 +0200 Subject: enhance: uniform theme color (#8702) * enhance: make theme color format uniform All newly fetched instance theme colors will be uniformely formatted as hashtag followed by 6 hexadecimal digits. Colors are checked for validity and invalid colors are not handled. * better input validation for own theme color * migration to unify theme color formats Fixes theme colors of other instances as well as the local instance. * add changelog entry Co-authored-by: syuilo --- CHANGELOG.md | 3 ++ .../migration/1652859567549-uniform-themecolor.js | 38 ++++++++++++++++++++++ .../src/server/api/endpoints/admin/update-meta.ts | 2 +- .../src/services/fetch-instance-metadata.ts | 14 +++----- 4 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 packages/backend/migration/1652859567549-uniform-themecolor.js (limited to 'packages/backend/src/server/api/endpoints') diff --git a/CHANGELOG.md b/CHANGELOG.md index fb8b8fdee6..21ae948d0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,9 @@ You should also include the user name that made the change. - update dependencies @syuilo - enhance: display URL of QR code for TOTP registration @syuilo - make CAPTCHA required for signin to improve security @syuilo +- The theme color is now better validated. @Johann150 + Your own theme color may be unset if it was in an invalid format. + Admins should check their instance settings if in doubt. - Perform port diagnosis at startup only when Listen fails @mei23 ### Bugfixes diff --git a/packages/backend/migration/1652859567549-uniform-themecolor.js b/packages/backend/migration/1652859567549-uniform-themecolor.js new file mode 100644 index 0000000000..bc47143e54 --- /dev/null +++ b/packages/backend/migration/1652859567549-uniform-themecolor.js @@ -0,0 +1,38 @@ +import tinycolor from 'tinycolor2'; + +export class uniformThemecolor1652859567549 { + name = 'uniformThemecolor1652859567549' + + async up(queryRunner) { + const formatColor = (color) => { + let tc = new tinycolor(color); + if (color.isValid()) { + return color.toHexString(); + } else { + return null; + } + }; + + await Promise.all(queryRunner.query('SELECT "id", "themeColor" FROM "instance" WHERE "themeColor" IS NOT NULL') + .then(instances => instances.map(instance => { + // update theme color to uniform format, e.g. #00ff00 + // invalid theme colors get set to null + instance.color = formatColor(instance.color); + + return queryRunner.query('UPDATE "instance" SET "themeColor" = :themeColor WHERE "id" = :id', instance); + }))); + + // also fix own theme color + await queryRunner.query('SELECT "themeColor" FROM "meta" WHERE "themeColor" IS NOT NULL LIMIT 1') + .then(metas => { + if (metas.length > 0) { + return queryRunner.query('UPDATE "meta" SET "themeColor" = :color', { color: formatColor(metas[0].color) }); + } + }); + } + + async down(queryRunner) { + // The original representation is not stored, so migrating back is not possible. + // The new format also works in older versions so this is not a problem. + } +} diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index b23ee9e3df..09e43301b7 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -27,7 +27,7 @@ export const paramDef = { blockedHosts: { type: 'array', nullable: true, items: { type: 'string', } }, - themeColor: { type: 'string', nullable: true }, + themeColor: { type: 'string', nullable: true, pattern: '^#[0-9a-fA-F]{6}$' }, mascotImageUrl: { type: 'string', nullable: true }, bannerUrl: { type: 'string', nullable: true }, errorImageUrl: { type: 'string', nullable: true }, diff --git a/packages/backend/src/services/fetch-instance-metadata.ts b/packages/backend/src/services/fetch-instance-metadata.ts index d5294c5fe8..029c388dc2 100644 --- a/packages/backend/src/services/fetch-instance-metadata.ts +++ b/packages/backend/src/services/fetch-instance-metadata.ts @@ -1,5 +1,6 @@ import { DOMWindow, JSDOM } from 'jsdom'; import fetch from 'node-fetch'; +import tinycolor from 'tinycolor2'; import { getJson, getHtml, getAgentByUrl } from '@/misc/fetch.js'; import { Instance } from '@/models/entities/instance.js'; import { Instances } from '@/models/index.js'; @@ -208,16 +209,11 @@ async function fetchIconUrl(instance: Instance, doc: DOMWindow['document'] | nul } async function getThemeColor(doc: DOMWindow['document'] | null, manifest: Record | null): Promise { - if (doc) { - const themeColor = doc.querySelector('meta[name="theme-color"]')?.getAttribute('content'); + const themeColor = doc?.querySelector('meta[name="theme-color"]')?.getAttribute('content') || manifest?.theme_color; - if (themeColor) { - return themeColor; - } - } - - if (manifest) { - return manifest.theme_color; + if (themeColor) { + const color = new tinycolor(themeColor); + if (color.isValid()) return color.toHexString(); } return null; -- cgit v1.2.3-freya