2024.11.0-yumechinokuni.1 #9

Merged
yume merged 13 commits from develop into master 2024-11-10 02:06:13 -06:00
9 changed files with 111 additions and 32 deletions

View file

@ -1,8 +1,10 @@
## 2024.10.2 ## 2024.11.0
### General ### General
- Feat: コンテンツの表示にログインを必須にできるように - Feat: コンテンツの表示にログインを必須にできるように
- Feat: 過去のノートを非公開化/フォロワーのみ表示可能にできるように - Feat: 過去のノートを非公開化/フォロワーのみ表示可能にできるように
- Enhance: 依存関係の更新
- Enhance: l10nの更新
### Client ### Client
- Enhance: Bull DashboardでRelationship Queueの状態も確認できるように - Enhance: Bull DashboardでRelationship Queueの状態も確認できるように
@ -25,12 +27,14 @@
- Fix: リンク切れを修正 - Fix: リンク切れを修正
= Fix: ノート投稿ボタンにホバー時のスタイルが適用されていないのを修正 = Fix: ノート投稿ボタンにホバー時のスタイルが適用されていないのを修正
(Cherry-picked from https://github.com/taiyme/misskey/pull/305) (Cherry-picked from https://github.com/taiyme/misskey/pull/305)
- Fix: メールアドレス登録有効化時の「完了」ダイアログボックスの表示条件を修正
### Server ### Server
- Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように - Enhance: 起動前の疎通チェックで、DBとメイン以外のRedisの疎通確認も行うように
(Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588) (Based on https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/588)
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715) (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/715)
- fix(backend): フォロワーへのメッセージの絵文字をemojisに含めるように - Enhance: リモートユーザーの照会をオリジナルにリダイレクトするように
- Fix: フォロワーへのメッセージの絵文字をemojisに含めるように
- Fix: Nested proxy requestsを検出した際にブロックするように - Fix: Nested proxy requestsを検出した際にブロックするように
[ghsa-gq5q-c77c-v236](https://github.com/misskey-dev/misskey/security/advisories/ghsa-gq5q-c77c-v236) [ghsa-gq5q-c77c-v236](https://github.com/misskey-dev/misskey/security/advisories/ghsa-gq5q-c77c-v236)
- Fix: 招待コードの発行可能な残り数算出に使用すべきロールポリシーの値が違う問題を修正 - Fix: 招待コードの発行可能な残り数算出に使用すべきロールポリシーの値が違う問題を修正
@ -41,7 +45,6 @@
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/712) (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/712)
- Fix: FTT無効時にユーザーリストタイムラインが使用できない問題を修正 - Fix: FTT無効時にユーザーリストタイムラインが使用できない問題を修正
(Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/709) (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/709)
- Enhance: リモートユーザーの照会をオリジナルにリダイレクトするように
### Misskey.js ### Misskey.js
- Fix: Stream初期化時、別途WebSocketを指定する場合の型定義を修正 - Fix: Stream初期化時、別途WebSocketを指定する場合の型定義を修正

View file

@ -85,6 +85,7 @@ Be willing to comment on the good points and not just the things you want fixed
読んでおくといいやつ 読んでおくといいやつ
- https://blog.lacolaco.net/posts/1e2cf439b3c2/ - https://blog.lacolaco.net/posts/1e2cf439b3c2/
- https://konifar-zatsu.hatenadiary.jp/entry/2024/11/05/192421
### Review perspective ### Review perspective
- Scope - Scope

View file

@ -1,6 +1,6 @@
{ {
"name": "misskey", "name": "misskey",
"version": "2024.11.0-yumechinokuni.0", "version": "2024.11.0-yumechinokuni.1",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -155,6 +155,8 @@ export type Config = {
signToActivityPubGet: boolean | undefined; signToActivityPubGet: boolean | undefined;
version: string; version: string;
gitDescribe: string;
gitCommit: string;
publishTarballInsteadOfProvideRepositoryUrl: boolean; publishTarballInsteadOfProvideRepositoryUrl: boolean;
setupPassword: string | undefined; setupPassword: string | undefined;
host: string; host: string;
@ -218,7 +220,7 @@ export function loadConfig(): Config {
const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source; const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source;
const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? ''); const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? '');
const version = meta.version; const { version, gitDescribe, gitCommit } = meta;
const host = url.host; const host = url.host;
const hostname = url.hostname; const hostname = url.hostname;
const scheme = url.protocol.replace(/:$/, ''); const scheme = url.protocol.replace(/:$/, '');
@ -236,6 +238,8 @@ export function loadConfig(): Config {
return { return {
version, version,
gitCommit,
gitDescribe,
publishTarballInsteadOfProvideRepositoryUrl: !!config.publishTarballInsteadOfProvideRepositoryUrl, publishTarballInsteadOfProvideRepositoryUrl: !!config.publishTarballInsteadOfProvideRepositoryUrl,
setupPassword: config.setupPassword, setupPassword: config.setupPassword,
url: url.origin, url: url.origin,

View file

@ -105,6 +105,8 @@ export class NodeinfoServerService {
name: meta.maintainerName, name: meta.maintainerName,
email: meta.maintainerEmail, email: meta.maintainerEmail,
}, },
gitCommit: this.config.gitCommit,
gitDescribe: this.config.gitDescribe,
langs: meta.langs, langs: meta.langs,
tosUrl: meta.termsOfServiceUrl, tosUrl: meta.termsOfServiceUrl,
privacyPolicyUrl: meta.privacyPolicyUrl, privacyPolicyUrl: meta.privacyPolicyUrl,

View file

@ -277,7 +277,7 @@ async function onSubmit(): Promise<void> {
return null; return null;
}); });
if (res) { if (res && res.ok) {
if (res.status === 204 || instance.emailRequiredForSignup) { if (res.status === 204 || instance.emailRequiredForSignup) {
os.alert({ os.alert({
type: 'success', type: 'success',
@ -295,6 +295,8 @@ async function onSubmit(): Promise<void> {
await login(resJson.token); await login(resJson.token);
} }
} }
} else {
onSignupApiError();
} }
submitting.value = false; submitting.value = false;

View file

@ -7,45 +7,91 @@ import * as Misskey from 'misskey-js';
import { markRaw } from 'vue'; import { markRaw } from 'vue';
import { $i } from '@/account.js'; import { $i } from '@/account.js';
import { wsOrigin } from '@@/js/config.js'; import { wsOrigin } from '@@/js/config.js';
import { DEFAULT_DEVICE_KIND } from '@/scripts/device-kind.js';
// TODO: No WebsocketモードでStreamMockが使えそう // TODO: No WebsocketモードでStreamMockが使えそう
//import { StreamMock } from '@/scripts/stream-mock.js'; //import { StreamMock } from '@/scripts/stream-mock.js';
// heart beat interval in ms // heart beat interval in ms
const HEART_BEAT_INTERVAL = 1000 * 60; const HEART_BEAT_INTERVAL = DEFAULT_DEVICE_KIND === 'desktop' ? 1000 * 15 : 1000 * 30;
const RECONNECT_MAX_ATTEMPTS = 10;
const RECONNECT_INITIAL_DELAY = 1000;
const RECONNECT_MAX_DELAY = 1000 * 30;
let stream: Misskey.IStream | null = null; let stream: Misskey.IStream | null = null;
let timeoutHeartBeat: number | null = null; let timeoutHeartBeat: number | null = null;
let lastHeartbeatCall = 0; let lastHeartbeatCall = 0;
let reconnectAttempts = 0;
let reconnectTimeout: number | null = null;
function getReconnectDelay(): number {
const delay = RECONNECT_INITIAL_DELAY * Math.pow(2, reconnectAttempts);
return Math.min(delay, RECONNECT_MAX_DELAY);
}
function createStream(): Misskey.IStream {
const newStream = markRaw(new Misskey.Stream(wsOrigin, $i ? {
token: $i.token,
} : null));
newStream.on('_disconnected_', () => {
console.log('Stream disconnected, attempting to reconnect...');
if (reconnectAttempts < RECONNECT_MAX_ATTEMPTS) {
const delay = getReconnectDelay();
reconnectTimeout = window.setTimeout(() => {
reconnectAttempts++;
stream = null;
useStream();
}, delay);
} else {
console.error('Max reconnection attempts reached');
}
});
newStream.on('_connected_', () => {
console.log('Stream connected successfully');
reconnectAttempts = 0;
if (reconnectTimeout) {
clearTimeout(reconnectTimeout);
reconnectTimeout = null;
}
});
return newStream;
}
export function useStream(): Misskey.IStream { export function useStream(): Misskey.IStream {
if (stream) return stream; if (stream) return stream;
// TODO: No Websocketモードもここで判定 stream = createStream();
stream = markRaw(new Misskey.Stream(wsOrigin, $i ? {
token: $i.token,
} : null));
if (timeoutHeartBeat) window.clearTimeout(timeoutHeartBeat); if (timeoutHeartBeat) window.clearTimeout(timeoutHeartBeat);
timeoutHeartBeat = window.setTimeout(heartbeat, HEART_BEAT_INTERVAL); timeoutHeartBeat = window.setTimeout(heartbeat, HEART_BEAT_INTERVAL);
// send heartbeat right now when last send time is over HEART_BEAT_INTERVAL const target = () => {
document.addEventListener('visibilitychange', () => { if (
if ( !stream
!stream || document.visibilityState !== 'visible'
|| document.visibilityState !== 'visible' || Date.now() - lastHeartbeatCall < HEART_BEAT_INTERVAL
|| Date.now() - lastHeartbeatCall < HEART_BEAT_INTERVAL ) return;
) return; heartbeat();
heartbeat(); };
});
return stream; // send heartbeat right now when last send time is over HEART_BEAT_INTERVAL
document.addEventListener('visibilitychange', target);
stream.on('_disconnected_', () => {
document.removeEventListener('visibilitychange', target);
});
return stream;
} }
function heartbeat(): void { function heartbeat(): void {
if (stream != null && document.visibilityState === 'visible') { if (stream != null && document.visibilityState === 'visible') {
stream.heartbeat(); stream.heartbeat();
} }
lastHeartbeatCall = Date.now(); lastHeartbeatCall = Date.now();
if (timeoutHeartBeat) window.clearTimeout(timeoutHeartBeat); if (timeoutHeartBeat) window.clearTimeout(timeoutHeartBeat);
timeoutHeartBeat = window.setTimeout(heartbeat, HEART_BEAT_INTERVAL); timeoutHeartBeat = window.setTimeout(heartbeat, HEART_BEAT_INTERVAL);
} }

View file

@ -4,14 +4,23 @@
*/ */
const fs = require('fs'); const fs = require('fs');
const child_process = require('child_process');
const packageJsonPath = __dirname + '/../package.json' const packageJsonPath = __dirname + '/../package.json'
function build() { function build() {
try { try {
const gitDescribe = child_process.execSync('git describe --tags --always').toString().trim();
const gitCommit = child_process.execSync('git rev-parse HEAD').toString().trim();
const json = fs.readFileSync(packageJsonPath, 'utf-8') const json = fs.readFileSync(packageJsonPath, 'utf-8')
const meta = JSON.parse(json); const meta = JSON.parse(json);
fs.mkdirSync(__dirname + '/../built', { recursive: true }); fs.mkdirSync(__dirname + '/../built', { recursive: true });
fs.writeFileSync(__dirname + '/../built/meta.json', JSON.stringify({ version: meta.version }), 'utf-8'); fs.writeFileSync(__dirname + '/../built/meta.json',
JSON.stringify(
{
version: meta.version,
gitCommit: gitCommit,
gitDescribe: gitDescribe,
}), 'utf-8');
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} }

View file

@ -49,6 +49,7 @@ pub struct RefConfig {
pub stdout: Option<PathBuf>, pub stdout: Option<PathBuf>,
pub stderr: Option<PathBuf>, pub stderr: Option<PathBuf>,
pub working_dir: PathBuf, pub working_dir: PathBuf,
pub profiles: Option<Vec<String>>,
pub compose_flags: Option<Vec<String>>, pub compose_flags: Option<Vec<String>>,
pub env: Option<HashMap<String, String>>, pub env: Option<HashMap<String, String>>,
pub uid: u32, pub uid: u32,
@ -200,6 +201,17 @@ impl App {
let mut command = Command::new("docker") let mut command = Command::new("docker")
.arg("compose") .arg("compose")
.args(
matched_ref
.config
.profiles
.as_ref()
.map(|profiles|
profiles.iter()
.flat_map(|profiles| ["--profile", profiles.as_str()])
.collect::<Vec<_>>())
.unwrap_or(Vec::new()),
)
.arg("up") .arg("up")
.arg("--detach") .arg("--detach")
.arg("--build") .arg("--build")
@ -289,7 +301,7 @@ impl App {
State(state): State<AppState>, State(state): State<AppState>,
Query(query): Query<GetStatusQuery>, Query(query): Query<GetStatusQuery>,
) -> Result<Json<RefStatus>, ApiError> { ) -> Result<Json<RefStatus>, ApiError> {
let ref_ = match (&query.ref_, &query.branch) { let ref_ = match (query.ref_.as_ref(), query.branch.as_ref()) {
(Some(ref_), None) => ref_.clone(), (Some(ref_), None) => ref_.clone(),
(None, Some(branch)) => format!("refs/heads/{}", branch), (None, Some(branch)) => format!("refs/heads/{}", branch),
_ => { _ => {