mirror of
https://github.com/kokonect-link/cherrypick
synced 2025-01-08 02:43:59 +09:00
Merge branch 'develop' into feat-13070
This commit is contained in:
commit
c56abec648
67
.github/workflows/deploy-test-environment.yml
vendored
67
.github/workflows/deploy-test-environment.yml
vendored
@ -1,66 +1,23 @@
|
||||
name: Deploy test environment
|
||||
name: deploy-test-environment
|
||||
|
||||
on:
|
||||
push:
|
||||
#push:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
repository:
|
||||
description: 'Repository to deploy (optional)'
|
||||
type: string
|
||||
required: false
|
||||
branch:
|
||||
description: 'Branch to deploy (optional)'
|
||||
branch_or_hash:
|
||||
description: 'Branch or Commit hash to deploy (optional)'
|
||||
type: string
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
deploy-test-environment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set environment variable (for tput command & pnpm)
|
||||
run: |
|
||||
echo "TERM=xterm" >> $GITHUB_ENV
|
||||
REPOSITORY=${{ github.event.inputs.repository || github.repository }}
|
||||
echo "REPOSITORY=$REPOSITORY" >> $GITHUB_ENV
|
||||
BRANCH=${{ github.event.inputs.branch || github.ref_name }}
|
||||
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ env.REPOSITORY }}
|
||||
ref: ${{ env.BRANCH }}
|
||||
|
||||
- name: Get the latest commit SHA
|
||||
run: |
|
||||
SHA=$(git log -1 --format="%H")
|
||||
echo "SHA=$SHA" >> $GITHUB_ENV
|
||||
|
||||
- name: Start cloudflare tunnel (quick)
|
||||
run: |
|
||||
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
|
||||
sudo dpkg -i cloudflared-linux-amd64.deb
|
||||
sudo cloudflared tunnel --metrics localhost:55555 --url localhost:3000 > /dev/null 2>&1 &
|
||||
sleep 15
|
||||
TUNNEL_RESPONSE=$(curl http://localhost:55555/quicktunnel)
|
||||
TUNNEL_DOMAIN=$(echo $TUNNEL_RESPONSE | grep -o '"hostname":"[^"]*' | grep -o '[^"]*$')
|
||||
echo "::add-mask::$TUNNEL_DOMAIN"
|
||||
echo "TUNNEL_DOMAIN=$TUNNEL_DOMAIN" >> $GITHUB_ENV
|
||||
|
||||
- name: Install misskey
|
||||
run: |
|
||||
wget https://raw.githubusercontent.com/joinmisskey/bash-install/v4/misskey-install.sh
|
||||
wget https://raw.githubusercontent.com/joinmisskey/bash-install/v4/testenv_githubactions.txt
|
||||
sed -i "s/host=127.0.0.1/host=$TUNNEL_DOMAIN/g" testenv_githubactions.txt
|
||||
sed -i "s|git_repository=https://github.com/misskey-dev/misskey|git_repository=https://github.com/$REPOSITORY|g" testenv_githubactions.txt
|
||||
sed -i "s|git_branch=master|git_branch=$BRANCH|g" testenv_githubactions.txt
|
||||
sudo chmod 555 ./misskey-install.sh
|
||||
sudo bash -x ./misskey-install.sh -c ./testenv_githubactions.txt
|
||||
|
||||
- name: Post tunnel info to Discord
|
||||
run: |
|
||||
CURRENT_TIME=$(TZ=Asia/Tokyo date +'%Y-%m-%d %H:%M:%S JST')
|
||||
COMMIT_URL="https://github.com/$REPOSITORY/commit/$SHA"
|
||||
curl -X POST -H "Content-Type: application/json" -d "{\"content\": \"==============================\nURL: https://$TUNNEL_DOMAIN\nRepository: $REPOSITORY\nBranch: $BRANCH\nCommit: $COMMIT_URL\nTime: $CURRENT_TIME\n==============================\"}" ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Wait
|
||||
run: |
|
||||
timeout 3600 tail -f /var/log/syslog || true
|
||||
uses: joinmisskey/misskey-tga/.github/workflows/deploy-test-environment.yml@main
|
||||
with:
|
||||
repository: ${{ github.event.inputs.repository }}
|
||||
branch_or_hash: ${{ github.event.inputs.branch_or_hash }}
|
||||
secrets:
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
2
.github/workflows/ok-to-test.yml
vendored
2
.github/workflows/ok-to-test.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }}
|
||||
|
||||
- name: Slash Command Dispatch
|
||||
uses: peter-evans/slash-command-dispatch@v3
|
||||
uses: peter-evans/slash-command-dispatch@v4
|
||||
env:
|
||||
TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||
with:
|
||||
|
4
.github/workflows/test-backend.yml
vendored
4
.github/workflows/test-backend.yml
vendored
@ -61,7 +61,7 @@ jobs:
|
||||
- name: Test
|
||||
run: pnpm --filter backend test-and-coverage
|
||||
- name: Upload to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/backend/coverage/coverage-final.json
|
||||
@ -111,7 +111,7 @@ jobs:
|
||||
- name: Test
|
||||
run: pnpm --filter backend test-and-coverage:e2e
|
||||
- name: Upload to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/backend/coverage/coverage-final.json
|
||||
|
2
.github/workflows/test-frontend.yml
vendored
2
.github/workflows/test-frontend.yml
vendored
@ -53,7 +53,7 @@ jobs:
|
||||
- name: Test
|
||||
run: pnpm --filter frontend test-and-coverage
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/frontend/coverage/coverage-final.json
|
||||
|
2
.github/workflows/test-misskey-js.yml
vendored
2
.github/workflows/test-misskey-js.yml
vendored
@ -50,7 +50,7 @@ jobs:
|
||||
CI: true
|
||||
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/misskey-js/coverage/coverage-final.json
|
||||
|
@ -21,6 +21,9 @@
|
||||
- Feat: [mCaptcha](https://github.com/mCaptcha/mCaptcha)のサポートを追加
|
||||
- Fix: リストライムラインの「リノートを表示」が正しく機能しない問題を修正
|
||||
- Feat: Add support for TrueMail
|
||||
- Fix: リモートユーザーのリアクション一覧がすべて見えてしまうのを修正
|
||||
* すべてのリモートユーザーのリアクション一覧を見えないようにします
|
||||
- Enhance: モデレーターはすべてのユーザーのリアクション一覧を見られるように
|
||||
|
||||
### Client
|
||||
- Feat: 新しいゲームを追加
|
||||
@ -71,6 +74,7 @@
|
||||
- Fix: ipv4とipv6の両方が利用可能な環境でallowedPrivateNetworksが設定されていた場合プライベートipの検証ができていなかった問題を修正
|
||||
- Fix: properly handle cc followers
|
||||
- Fix: ジョブに関する設定の名前を修正 relashionshipJobPerSec -> relationshipJobPerSec
|
||||
- Fix: コントロールパネル->モデレーション->「誰でも新規登録できるようにする」の初期値をONからOFFに変更 #13122
|
||||
|
||||
### Service Worker
|
||||
- Enhance: オフライン表示のデザインを改善・多言語対応
|
||||
|
@ -3,6 +3,6 @@ import { genOpenapiSpec } from './built/server/api/openapi/gen-spec.js'
|
||||
import { writeFileSync } from "node:fs";
|
||||
|
||||
const config = loadConfig();
|
||||
const spec = genOpenapiSpec(config);
|
||||
const spec = genOpenapiSpec(config, true);
|
||||
|
||||
writeFileSync('./built/api.json', JSON.stringify(spec), 'utf-8');
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class FixMetaDisableRegistration1706791962000 {
|
||||
name = 'FixMetaDisableRegistration1706791962000'
|
||||
|
||||
async up(queryRunner) {
|
||||
await queryRunner.query(`alter table meta alter column "disableRegistration" set default true;`);
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
await queryRunner.query(`alter table meta alter column "disableRegistration" set default false;`);
|
||||
}
|
||||
}
|
@ -409,7 +409,7 @@ export class UserEntityService implements OnModuleInit {
|
||||
}),
|
||||
pinnedPageId: profile!.pinnedPageId,
|
||||
pinnedPage: profile!.pinnedPageId ? this.pageEntityService.pack(profile!.pinnedPageId, me) : null,
|
||||
publicReactions: profile!.publicReactions,
|
||||
publicReactions: this.isLocalUser(user) ? profile!.publicReactions : false, // https://github.com/misskey-dev/misskey/issues/12964
|
||||
followersVisibility: profile!.followersVisibility,
|
||||
followingVisibility: profile!.followingVisibility,
|
||||
twoFactorEnabled: profile!.twoFactorEnabled,
|
||||
|
@ -119,6 +119,7 @@ export interface Schema extends OfSchema {
|
||||
readonly example?: any;
|
||||
readonly format?: string;
|
||||
readonly ref?: keyof typeof refs;
|
||||
readonly selfRef?: boolean;
|
||||
readonly enum?: ReadonlyArray<string | null>;
|
||||
readonly default?: (this['type'] extends TypeStringef ? StringDefToType<this['type']> : any) | null;
|
||||
readonly maxLength?: number;
|
||||
|
@ -53,6 +53,7 @@ const sectionBlockSchema = {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
ref: 'PageBlock',
|
||||
selfRef: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -9,6 +9,9 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { QueryService } from '@/core/QueryService.js';
|
||||
import { NoteReactionEntityService } from '@/core/entities/NoteReactionEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { CacheService } from '@/core/CacheService.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { RoleService } from '@/core/RoleService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
|
||||
export const meta = {
|
||||
@ -34,6 +37,11 @@ export const meta = {
|
||||
code: 'REACTIONS_NOT_PUBLIC',
|
||||
id: '673a7dd2-6924-1093-e0c0-e68456ceae5c',
|
||||
},
|
||||
isRemoteUser: {
|
||||
message: 'Currently unavailable to display reactions of remote users. See https://github.com/misskey-dev/misskey/issues/12964',
|
||||
code: 'IS_REMOTE_USER',
|
||||
id: '6b95fa98-8cf9-2350-e284-f0ffdb54a805',
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
@ -59,14 +67,24 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||
@Inject(DI.noteReactionsRepository)
|
||||
private noteReactionsRepository: NoteReactionsRepository,
|
||||
|
||||
private cacheService: CacheService,
|
||||
private userEntityService: UserEntityService,
|
||||
private noteReactionEntityService: NoteReactionEntityService,
|
||||
private queryService: QueryService,
|
||||
private roleService: RoleService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: ps.userId });
|
||||
const iAmModerator = me ? await this.roleService.isModerator(me) : false; // Moderators can see reactions of all users
|
||||
if (!iAmModerator) {
|
||||
const user = await this.cacheService.findUserById(ps.userId);
|
||||
if (this.userEntityService.isRemoteUser(user)) {
|
||||
throw new ApiError(meta.errors.isRemoteUser);
|
||||
}
|
||||
|
||||
if ((me == null || me.id !== ps.userId) && !profile.publicReactions) {
|
||||
throw new ApiError(meta.errors.reactionsNotPublic);
|
||||
const profile = await this.userProfilesRepository.findOneByOrFail({ userId: ps.userId });
|
||||
if ((me == null || me.id !== ps.userId) && !profile.publicReactions) {
|
||||
throw new ApiError(meta.errors.reactionsNotPublic);
|
||||
}
|
||||
}
|
||||
|
||||
const query = this.queryService.makePaginationQuery(this.noteReactionsRepository.createQueryBuilder('reaction'),
|
||||
|
@ -6,9 +6,9 @@
|
||||
import type { Config } from '@/config.js';
|
||||
import endpoints, { IEndpoint } from '../endpoints.js';
|
||||
import { errors as basicErrors } from './errors.js';
|
||||
import { schemas, convertSchemaToOpenApiSchema } from './schemas.js';
|
||||
import { getSchemas, convertSchemaToOpenApiSchema } from './schemas.js';
|
||||
|
||||
export function genOpenapiSpec(config: Config) {
|
||||
export function genOpenapiSpec(config: Config, includeSelfRef = false) {
|
||||
const spec = {
|
||||
openapi: '3.1.0',
|
||||
|
||||
@ -30,7 +30,7 @@ export function genOpenapiSpec(config: Config) {
|
||||
paths: {} as any,
|
||||
|
||||
components: {
|
||||
schemas: schemas,
|
||||
schemas: getSchemas(includeSelfRef),
|
||||
|
||||
securitySchemes: {
|
||||
bearerAuth: {
|
||||
@ -56,7 +56,7 @@ export function genOpenapiSpec(config: Config) {
|
||||
}
|
||||
}
|
||||
|
||||
const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res, 'res') : {};
|
||||
const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res, 'res', includeSelfRef) : {};
|
||||
|
||||
let desc = (endpoint.meta.description ? endpoint.meta.description : 'No description provided.') + '\n\n';
|
||||
|
||||
@ -71,7 +71,7 @@ export function genOpenapiSpec(config: Config) {
|
||||
}
|
||||
|
||||
const requestType = endpoint.meta.requireFile ? 'multipart/form-data' : 'application/json';
|
||||
const schema = { ...convertSchemaToOpenApiSchema(endpoint.params, 'param') };
|
||||
const schema = { ...convertSchemaToOpenApiSchema(endpoint.params, 'param', false) };
|
||||
|
||||
if (endpoint.meta.requireFile) {
|
||||
schema.properties = {
|
||||
|
@ -6,10 +6,10 @@
|
||||
import type { Schema } from '@/misc/json-schema.js';
|
||||
import { refs } from '@/misc/json-schema.js';
|
||||
|
||||
export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res') {
|
||||
export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res', includeSelfRef: boolean): any {
|
||||
// optional, nullable, refはスキーマ定義に含まれないので分離しておく
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { optional, nullable, ref, ...res }: any = schema;
|
||||
const { optional, nullable, ref, selfRef, ...res }: any = schema;
|
||||
|
||||
if (schema.type === 'object' && schema.properties) {
|
||||
if (type === 'res') {
|
||||
@ -21,20 +21,20 @@ export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 're
|
||||
}
|
||||
|
||||
for (const k of Object.keys(schema.properties)) {
|
||||
res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k], type);
|
||||
res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k], type, includeSelfRef);
|
||||
}
|
||||
}
|
||||
|
||||
if (schema.type === 'array' && schema.items) {
|
||||
res.items = convertSchemaToOpenApiSchema(schema.items, type);
|
||||
res.items = convertSchemaToOpenApiSchema(schema.items, type, includeSelfRef);
|
||||
}
|
||||
|
||||
for (const o of ['anyOf', 'oneOf', 'allOf'] as const) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
if (o in schema) res[o] = schema[o]!.map(schema => convertSchemaToOpenApiSchema(schema, type));
|
||||
if (o in schema) res[o] = schema[o]!.map(schema => convertSchemaToOpenApiSchema(schema, type, includeSelfRef));
|
||||
}
|
||||
|
||||
if (type === 'res' && schema.ref) {
|
||||
if (type === 'res' && schema.ref && (!schema.selfRef || includeSelfRef)) {
|
||||
const $ref = `#/components/schemas/${schema.ref}`;
|
||||
if (schema.nullable || schema.optional) {
|
||||
res.allOf = [{ $ref }];
|
||||
@ -54,35 +54,37 @@ export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 're
|
||||
return res;
|
||||
}
|
||||
|
||||
export const schemas = {
|
||||
Error: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
error: {
|
||||
type: 'object',
|
||||
description: 'An error object.',
|
||||
properties: {
|
||||
code: {
|
||||
type: 'string',
|
||||
description: 'An error code. Unique within the endpoint.',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'An error message.',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'uuid',
|
||||
description: 'An error ID. This ID is static.',
|
||||
export function getSchemas(includeSelfRef: boolean) {
|
||||
return {
|
||||
Error: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
error: {
|
||||
type: 'object',
|
||||
description: 'An error object.',
|
||||
properties: {
|
||||
code: {
|
||||
type: 'string',
|
||||
description: 'An error code. Unique within the endpoint.',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'An error message.',
|
||||
},
|
||||
id: {
|
||||
type: 'string',
|
||||
format: 'uuid',
|
||||
description: 'An error ID. This ID is static.',
|
||||
},
|
||||
},
|
||||
required: ['code', 'id', 'message'],
|
||||
},
|
||||
required: ['code', 'id', 'message'],
|
||||
},
|
||||
required: ['error'],
|
||||
},
|
||||
required: ['error'],
|
||||
},
|
||||
|
||||
...Object.fromEntries(
|
||||
Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema, 'res')]),
|
||||
),
|
||||
};
|
||||
...Object.fromEntries(
|
||||
Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema, 'res', includeSelfRef)]),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
@ -263,7 +263,12 @@ const translation = ref<Misskey.entities.NotesTranslateResponse | null>(null);
|
||||
const translating = ref(false);
|
||||
const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);
|
||||
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || (appearNote.value.visibility === 'followers' && appearNote.value.userId === $i?.id));
|
||||
const renoteCollapsed = ref(defaultStore.state.collapseRenotes && isRenote && (($i && ($i.id === note.value.userId || $i.id === appearNote.value.userId)) ?? (appearNote.value.myReaction != null)));
|
||||
const renoteCollapsed = ref(
|
||||
defaultStore.state.collapseRenotes && isRenote && (
|
||||
($i && ($i.id === note.value.userId || $i.id === appearNote.value.userId)) || // `||` must be `||`! See https://github.com/misskey-dev/misskey/issues/13131
|
||||
(appearNote.value.myReaction != null)
|
||||
)
|
||||
);
|
||||
|
||||
/* Overload FunctionにLintが対応していないのでコメントアウト
|
||||
function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean;
|
||||
|
@ -96,7 +96,7 @@ const headerTabs = computed(() => user.value ? [{
|
||||
key: 'achievements',
|
||||
title: i18n.ts.achievements,
|
||||
icon: 'ti ti-medal',
|
||||
}] : []), ...($i && ($i.id === user.value.id)) || user.value.publicReactions ? [{
|
||||
}] : []), ...($i && ($i.id === user.value.id || $i.isAdmin || $i.isModerator)) || user.value.publicReactions ? [{
|
||||
key: 'reactions',
|
||||
title: i18n.ts.reaction,
|
||||
icon: 'ti ti-mood-happy',
|
||||
|
Loading…
Reference in New Issue
Block a user