diff options
| author | Freya Murphy <freya@freyacat.org> | 2026-03-02 16:05:12 -0500 |
|---|---|---|
| committer | Freya Murphy <freya@freyacat.org> | 2026-03-02 18:39:22 -0500 |
| commit | 24734d408700a72d45c3ff4a679606cab3ec544f (patch) | |
| tree | d0fee0bcf508f3c631f7c26724bb5cd94dfc88a0 | |
| parent | merge: Release/2025.4.5 (!1258) (diff) | |
| download | sharkey-stable.tar.gz sharkey-stable.tar.bz2 sharkey-stable.zip | |
split url into webUrl and localUrl (like mastodon)stable
Diffstat (limited to '')
142 files changed, 402 insertions, 382 deletions
diff --git a/packages/backend/src/GlobalModule.ts b/packages/backend/src/GlobalModule.ts index 90dbdaf2a6..0f6c0c6cd7 100644 --- a/packages/backend/src/GlobalModule.ts +++ b/packages/backend/src/GlobalModule.ts @@ -70,7 +70,7 @@ const $redisForSub: Provider = { provide: DI.redisForSub, useFactory: (config: Config) => { const redis = new Redis.Redis(config.redisForPubsub); - redis.subscribe(config.host); + redis.subscribe(config.webHost); return redis; }, inject: [DI.config], diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts index a90228eabc..234312b06f 100644 --- a/packages/backend/src/boot/master.ts +++ b/packages/backend/src/boot/master.ts @@ -143,7 +143,7 @@ export async function masterMain() { bootLogger.info('Queue started', null, true); } else { const addressString = net.isIPv6(config.address) ? `[${config.address}]` : config.address; - bootLogger.info(config.socket ? `Now listening on socket ${config.socket} on ${config.url}` : `Now listening on ${addressString}:${config.port} on ${config.url}`, null, true); + bootLogger.info(config.socket ? `Now listening on socket ${config.socket} on ${config.localUrl}` : `Now listening on ${addressString}:${config.port} on ${config.localUrl}`, null, true); } } diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index c2e7efd456..06f73fdb21 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -30,6 +30,8 @@ type RedisOptionsSource = Partial<RedisOptions> & { */ type Source = { url?: string; + localUrl?: string; + webUrl?: string; port?: number; address?: string; socket?: string; @@ -214,7 +216,8 @@ function parseIpOrMask(ipOrMask: string): CIDR | null { } export type Config = { - url: string; + localUrl: string; + webUrl: string; port: number; address: string; socket: string | undefined; @@ -290,8 +293,10 @@ export type Config = { version: string; publishTarballInsteadOfProvideRepositoryUrl: boolean; setupPassword: string | undefined; - host: string; - hostname: string; + localHost: string; + localHostname: string; + webHost: string; + webHostname: string; scheme: string; wsScheme: string; apiUrl: string; @@ -396,11 +401,14 @@ export function loadConfig(): Config { applyEnvOverrides(config); - const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? ''); + const localUrl = tryCreateUrl(config.url ?? config.localUrl ?? process.env.MISSKEY_URL ?? ''); + const webUrl = tryCreateUrl(config.webUrl ?? process.env.MISSKEY_WEB_URL ?? localUrl ?? ''); const version = meta.version; - const host = url.host; - const hostname = url.hostname; - const scheme = url.protocol.replace(/:$/, ''); + const localHost = localUrl.host; + const localHostname = localUrl.hostname; + const webHost = webUrl.host; + const webHostname = webUrl.hostname; + const scheme = webUrl.protocol.replace(/:$/, ''); const wsScheme = scheme.replace('http', 'ws'); const dbDb = config.db.db ?? process.env.DATABASE_DB ?? ''; @@ -410,8 +418,8 @@ export function loadConfig(): Config { const externalMediaProxy = config.mediaProxy ? config.mediaProxy.endsWith('/') ? config.mediaProxy.substring(0, config.mediaProxy.length - 1) : config.mediaProxy : null; - const internalMediaProxy = `${scheme}://${host}/proxy`; - const redis = convertRedisOptions(config.redis, host); + const internalMediaProxy = `${scheme}://${webHost}/proxy`; + const redis = convertRedisOptions(config.redis, localHost); // nullish => 300 (default) // 0 => undefined (disabled) @@ -421,31 +429,34 @@ export function loadConfig(): Config { version, publishTarballInsteadOfProvideRepositoryUrl: !!config.publishTarballInsteadOfProvideRepositoryUrl, setupPassword: config.setupPassword, - url: url.origin, + localUrl: localUrl.origin, + webUrl: webUrl.origin, port: config.port ?? parseInt(process.env.PORT ?? '3000', 10), address: config.address ?? '0.0.0.0', socket: config.socket, chmodSocket: config.chmodSocket, disableHsts: config.disableHsts, - host, - hostname, + localHost, + localHostname, + webHost, + webHostname, scheme, wsScheme, - wsUrl: `${wsScheme}://${host}`, - apiUrl: `${scheme}://${host}/api`, - authUrl: `${scheme}://${host}/auth`, - driveUrl: `${scheme}://${host}/files`, + wsUrl: `${wsScheme}://${webHost}`, + apiUrl: `${scheme}://${webHost}/api`, + authUrl: `${scheme}://${webHost}/auth`, + driveUrl: `${scheme}://${webHost}/files`, db: { ...config.db, db: dbDb, user: dbUser, pass: dbPass, slowQueryThreshold }, dbReplications: config.dbReplications, dbSlaves: config.dbSlaves, fulltextSearch: config.fulltextSearch, meilisearch: config.meilisearch, redis, - redisForPubsub: config.redisForPubsub ? convertRedisOptions(config.redisForPubsub, host) : redis, - redisForJobQueue: config.redisForJobQueue ? convertRedisOptions(config.redisForJobQueue, host) : redis, - redisForTimelines: config.redisForTimelines ? convertRedisOptions(config.redisForTimelines, host) : redis, - redisForReactions: config.redisForReactions ? convertRedisOptions(config.redisForReactions, host) : redis, - redisForRateLimit: config.redisForRateLimit ? convertRedisOptions(config.redisForRateLimit, host) : redis, + redisForPubsub: config.redisForPubsub ? convertRedisOptions(config.redisForPubsub, webHost) : redis, + redisForJobQueue: config.redisForJobQueue ? convertRedisOptions(config.redisForJobQueue, webHost) : redis, + redisForTimelines: config.redisForTimelines ? convertRedisOptions(config.redisForTimelines, webHost) : redis, + redisForReactions: config.redisForReactions ? convertRedisOptions(config.redisForReactions, webHost) : redis, + redisForRateLimit: config.redisForRateLimit ? convertRedisOptions(config.redisForRateLimit, webHost) : redis, sentryForBackend: config.sentryForBackend, sentryForFrontend: config.sentryForFrontend, id: config.id, @@ -483,7 +494,7 @@ export function loadConfig(): Config { videoThumbnailGenerator: config.videoThumbnailGenerator ? config.videoThumbnailGenerator.endsWith('/') ? config.videoThumbnailGenerator.substring(0, config.videoThumbnailGenerator.length - 1) : config.videoThumbnailGenerator : null, - userAgent: `Misskey/${version} (${config.url})`, + userAgent: `Misskey/${version} (${config.localUrl})`, frontendEntry: frontendManifest['src/_boot_.ts'], frontendManifestExists: frontendManifestExists, frontendEmbedEntry: frontendEmbedManifest['src/boot.ts'], diff --git a/packages/backend/src/core/ChatService.ts b/packages/backend/src/core/ChatService.ts index 9d294a80cb..968419c5e9 100644 --- a/packages/backend/src/core/ChatService.ts +++ b/packages/backend/src/core/ChatService.ts @@ -369,7 +369,7 @@ export class ChatService { if (this.userEntityService.isLocalUser(toUser)) this.globalEventService.publishChatUserStream(message.toUserId, message.fromUserId, 'deleted', message.id); if (this.userEntityService.isLocalUser(fromUser) && this.userEntityService.isRemoteUser(toUser)) { - //const activity = this.apRendererService.addContext(this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.url}/notes/${message.id}`), fromUser)); + //const activity = this.apRendererService.addContext(this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.webUrl}/notes/${message.id}`), fromUser)); //this.queueService.deliver(fromUser, activity, toUser.inbox); } } else if (message.toRoomId) { diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 2e4eddf797..3b05a13518 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -411,7 +411,7 @@ export class CustomEmojiService implements OnApplicationShutdown { if (name == null) return null; if (host == null) return null; - const newHost = host === this.config.host ? null : host; + const newHost = host === this.config.localHost ? null : host; const queryOrNull = async () => (await this.emojisRepository.findOneBy({ name, diff --git a/packages/backend/src/core/EmailService.ts b/packages/backend/src/core/EmailService.ts index 45d7ea11e4..fe3b8ef8ef 100644 --- a/packages/backend/src/core/EmailService.ts +++ b/packages/backend/src/core/EmailService.ts @@ -42,8 +42,8 @@ export class EmailService { public async sendEmail(to: string, subject: string, html: string, text: string) { if (!this.meta.enableEmail) return; - const iconUrl = `${this.config.url}/static-assets/mi-white.png`; - const emailSettingUrl = `${this.config.url}/settings/email`; + const iconUrl = `${this.config.webUrl}/static-assets/mi-white.png`; + const emailSettingUrl = `${this.config.webUrl}/settings/email`; const enableAuth = this.meta.smtpUser != null && this.meta.smtpUser !== ''; @@ -135,7 +135,7 @@ export class EmailService { </footer> </main> <nav> - <a href="${ this.config.url }">${ this.config.host }</a> + <a href="${ this.config.webUrl }">${ this.config.webHost }</a> </nav> </body> </html>`; diff --git a/packages/backend/src/core/GlobalEventService.ts b/packages/backend/src/core/GlobalEventService.ts index c146811331..c35e7243d3 100644 --- a/packages/backend/src/core/GlobalEventService.ts +++ b/packages/backend/src/core/GlobalEventService.ts @@ -359,7 +359,7 @@ export class GlobalEventService { { type: type, body: null } : { type: type, body: value }; - await this.redisForPub.publish(this.config.host, JSON.stringify({ + await this.redisForPub.publish(this.config.webHost, JSON.stringify({ channel: channel, message: message, })); diff --git a/packages/backend/src/core/InternalStorageService.ts b/packages/backend/src/core/InternalStorageService.ts index abdbbc61d3..1b4f1880b9 100644 --- a/packages/backend/src/core/InternalStorageService.ts +++ b/packages/backend/src/core/InternalStorageService.ts @@ -48,7 +48,7 @@ export class InternalStorageService { const path = this.resolvePath(key); await chmod(path, this.config.filePermissionBits); } - return `${this.config.url}/files/${key}`; + return `${this.config.webUrl}/files/${key}`; } @bindThis diff --git a/packages/backend/src/core/MfmService.ts b/packages/backend/src/core/MfmService.ts index 839cdf534c..33a009fa50 100644 --- a/packages/backend/src/core/MfmService.ts +++ b/packages/backend/src/core/MfmService.ts @@ -491,7 +491,7 @@ export class MfmService { hashtag: (node) => { const a = new Element('a', { - href: `${this.config.url}/tags/${node.props.hashtag}`, + href: `${this.config.webUrl}/tags/${node.props.hashtag}`, rel: 'tag', }); a.childNodes.push(new Text(`#${node.props.hashtag}`)); @@ -531,7 +531,7 @@ export class MfmService { const a = new Element('a', { href: remoteUserInfo ? (remoteUserInfo.url ? remoteUserInfo.url : remoteUserInfo.uri) - : `${this.config.url}/${acct.endsWith(`@${this.config.url}`) ? acct.substring(0, acct.length - this.config.url.length - 1) : acct}`, + : `${this.config.webUrl}/${acct.endsWith(`@${this.config.localUrl}`) ? acct.substring(0, acct.length - this.config.localUrl.length - 1) : acct}`, class: 'u-url mention', }); a.childNodes.push(new Text(acct)); @@ -747,7 +747,7 @@ export class MfmService { hashtag: (node) => { const a = new Element('a', { - href: `${this.config.url}/tags/${node.props.hashtag}`, + href: `${this.config.webUrl}/tags/${node.props.hashtag}`, rel: 'tag', class: 'hashtag', }); diff --git a/packages/backend/src/core/NoteDeleteService.ts b/packages/backend/src/core/NoteDeleteService.ts index 9ce8cb6731..1dcfc2cafd 100644 --- a/packages/backend/src/core/NoteDeleteService.ts +++ b/packages/backend/src/core/NoteDeleteService.ts @@ -103,8 +103,8 @@ export class NoteDeleteService { } const content = this.apRendererService.addContext(renote - ? this.apRendererService.renderUndo(this.apRendererService.renderAnnounce(renote.uri ?? `${this.config.url}/notes/${renote.id}`, note), user) - : this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.url}/notes/${note.id}`), user)); + ? this.apRendererService.renderUndo(this.apRendererService.renderAnnounce(renote.uri ?? `${this.config.webUrl}/notes/${renote.id}`, note), user) + : this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.webUrl}/notes/${note.id}`), user)); this.deliverToConcerned(user, note, content); } @@ -114,7 +114,7 @@ export class NoteDeleteService { for (const cascadingNote of federatedLocalCascadingNotes) { if (!cascadingNote.user) continue; if (!this.userEntityService.isLocalUser(cascadingNote.user)) continue; - const content = this.apRendererService.addContext(this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.url}/notes/${cascadingNote.id}`), cascadingNote.user)); + const content = this.apRendererService.addContext(this.apRendererService.renderDelete(this.apRendererService.renderTombstone(`${this.config.webUrl}/notes/${cascadingNote.id}`), cascadingNote.user)); this.deliverToConcerned(cascadingNote.user, cascadingNote, content); } //#endregion diff --git a/packages/backend/src/core/NotePiningService.ts b/packages/backend/src/core/NotePiningService.ts index a678108189..19bc3186df 100644 --- a/packages/backend/src/core/NotePiningService.ts +++ b/packages/backend/src/core/NotePiningService.ts @@ -120,8 +120,8 @@ export class NotePiningService { public async deliverPinnedChange(user: MiUser, noteId: MiNote['id'], isAddition: boolean) { if (!this.userEntityService.isLocalUser(user)) return; - const target = `${this.config.url}/users/${user.id}/collections/featured`; - const item = `${this.config.url}/notes/${noteId}`; + const target = `${this.config.webUrl}/users/${user.id}/collections/featured`; + const item = `${this.config.webUrl}/notes/${noteId}`; const content = this.apRendererService.addContext(isAddition ? this.apRendererService.renderAdd(user, target, item) : this.apRendererService.renderRemove(user, target, item)); await this.apDeliverManagerService.deliverToFollowers(user, content); diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts index e3f10d4504..85e22a0547 100644 --- a/packages/backend/src/core/PushNotificationService.ts +++ b/packages/backend/src/core/PushNotificationService.ts @@ -76,7 +76,7 @@ export class PushNotificationService implements OnApplicationShutdown { if (!this.meta.enableServiceWorker || this.meta.swPublicKey == null || this.meta.swPrivateKey == null) return; // アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録 - push.setVapidDetails(this.config.url, + push.setVapidDetails(this.config.webUrl, this.meta.swPublicKey, this.meta.swPrivateKey); diff --git a/packages/backend/src/core/RemoteUserResolveService.ts b/packages/backend/src/core/RemoteUserResolveService.ts index 4dbc9d6a36..883877b047 100644 --- a/packages/backend/src/core/RemoteUserResolveService.ts +++ b/packages/backend/src/core/RemoteUserResolveService.ts @@ -49,7 +49,7 @@ export class RemoteUserResolveService { host = this.utilityService.toPuny(host); - if (host === this.utilityService.toPuny(this.config.host)) { + if (host === this.utilityService.toPuny(this.config.localHost)) { return await this.usersRepository.findOneByOrFail({ usernameLower, host: IsNull() }) as MiLocalUser; } diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 8470872eac..b1229a353d 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -518,7 +518,7 @@ export class UserFollowingService implements OnModuleInit { } if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { - const content = this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiPartialLocalUser, followee as MiPartialRemoteUser, requestId ?? `${this.config.url}/follows/${followRequest.id}`)); + const content = this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiPartialLocalUser, followee as MiPartialRemoteUser, requestId ?? `${this.config.webUrl}/follows/${followRequest.id}`)); this.queueService.deliver(follower, content, followee.inbox, false); } } diff --git a/packages/backend/src/core/UserSearchService.ts b/packages/backend/src/core/UserSearchService.ts index 4be7bd9bdb..15245c39b7 100644 --- a/packages/backend/src/core/UserSearchService.ts +++ b/packages/backend/src/core/UserSearchService.ts @@ -198,7 +198,7 @@ export class UserSearchService { } if (params.host) { - if (params.host === this.config.hostname || params.host === '.') { + if (params.host === this.config.localHostname || params.host === '.') { userQuery.andWhere('user.host IS NULL'); } else { userQuery.andWhere('user.host LIKE :host', { diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts index a90774cf59..c15c587cd7 100644 --- a/packages/backend/src/core/UtilityService.ts +++ b/packages/backend/src/core/UtilityService.ts @@ -30,18 +30,20 @@ export class UtilityService { @bindThis public getFullApAccount(username: string, host: string | null): string { - return host ? `${username}@${this.toPuny(host)}` : `${username}@${this.toPuny(this.config.host)}`; + return host ? `${username}@${this.toPuny(host)}` : `${username}@${this.toPuny(this.config.localHost)}`; } @bindThis public isSelfHost(host: string | null): boolean { if (host == null) return true; - return this.toPuny(this.config.host) === this.toPuny(host); + return (this.toPuny(this.config.localHost) === this.toPuny(host)) || + (this.toPuny(this.config.webHost) === this.toPuny(host)) } @bindThis public isUriLocal(uri: string): boolean { - return this.punyHost(uri) === this.toPuny(this.config.host); + return (this.punyHost(uri) === this.toPuny(this.config.localHost)) || + (this.punyHost(uri) === this.toPuny(this.config.webHost)) } // メールアドレスのバリデーションを行う diff --git a/packages/backend/src/core/WebAuthnService.ts b/packages/backend/src/core/WebAuthnService.ts index afd1d68ce4..dc9899ff18 100644 --- a/packages/backend/src/core/WebAuthnService.ts +++ b/packages/backend/src/core/WebAuthnService.ts @@ -52,9 +52,9 @@ export class WebAuthnService { @bindThis public getRelyingParty(): { origin: string; rpId: string; rpName: string; rpIcon?: string; } { return { - origin: this.config.url, - rpId: this.config.hostname, - rpName: this.meta.name ?? this.config.host, + origin: this.config.webUrl, + rpId: this.config.webHostname, + rpName: this.meta.name ?? this.config.webHost, rpIcon: this.meta.iconUrl ?? undefined, }; } diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index e9e0dde9cd..73b81a1226 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -64,7 +64,8 @@ export class ApDbResolverService implements OnApplicationShutdown { const apId = getApId(value); const uri = new URL(apId); - if (this.utilityService.toPuny(uri.host) !== this.utilityService.toPuny(this.config.host)) { + if ((this.utilityService.toPuny(uri.host) !== this.utilityService.toPuny(this.config.localHost)) && + (this.utilityService.toPuny(uri.host) !== this.utilityService.toPuny(this.config.webHost))) { return { local: false, uri: apId }; } diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index 009d4cbd39..a7699c67d6 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -646,7 +646,7 @@ export class ApInboxService { const uris = getApIds(activity.object); const userIds = uris - .filter(uri => uri.startsWith(this.config.url + '/users/')) + .filter(uri => uri.startsWith(this.config.webUrl + '/users/')) .map(uri => uri.split('/').at(-1)) .filter(x => x != null); const users = await this.usersRepository.findBy({ diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 9f55be11ac..aa014505ee 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -121,7 +121,7 @@ export class ApRendererService { } return { - id: `${this.config.url}/notes/${note.id}/activity`, + id: `${this.config.webUrl}/notes/${note.id}/activity`, actor: this.userEntityService.genLocalUserUri(note.userId), type: 'Announce', published: this.idService.parse(note.id).date.toISOString(), @@ -144,7 +144,7 @@ export class ApRendererService { return { type: 'Block', - id: `${this.config.url}/blocks/${block.id}`, + id: `${this.config.webUrl}/blocks/${block.id}`, actor: this.userEntityService.genLocalUserUri(block.blockerId), object: block.blockee.uri, }; @@ -153,7 +153,7 @@ export class ApRendererService { @bindThis public renderCreate(object: IObject, note: MiNote): ICreate { const activity: ICreate = { - id: `${this.config.url}/notes/${note.id}/activity`, + id: `${this.config.webUrl}/notes/${note.id}/activity`, actor: this.userEntityService.genLocalUserUri(note.userId), type: 'Create', published: this.idService.parse(note.id).date.toISOString(), @@ -191,7 +191,7 @@ export class ApRendererService { @bindThis public renderEmoji(emoji: MiEmoji): IApEmoji { return { - id: `${this.config.url}/emojis/${emoji.name}`, + id: `${this.config.webUrl}/emojis/${emoji.name}`, type: 'Emoji', name: `:${emoji.name}:`, updated: emoji.updatedAt != null ? emoji.updatedAt.toISOString() : new Date().toISOString(), @@ -222,7 +222,7 @@ export class ApRendererService { @bindThis public renderFollowRelay(relay: MiRelay, relayActor: MiLocalUser): IFollow { return { - id: `${this.config.url}/activities/follow-relay/${relay.id}`, + id: `${this.config.webUrl}/activities/follow-relay/${relay.id}`, type: 'Follow', actor: this.userEntityService.genLocalUserUri(relayActor.id), object: 'https://www.w3.org/ns/activitystreams#Public', @@ -246,7 +246,7 @@ export class ApRendererService { requestId?: string, ): IFollow { return { - id: requestId ?? `${this.config.url}/follows/${follower.id}/${followee.id}`, + id: requestId ?? `${this.config.webUrl}/follows/${follower.id}/${followee.id}`, type: 'Follow', actor: this.userEntityService.getUserUri(follower), object: this.userEntityService.getUserUri(followee), @@ -257,7 +257,7 @@ export class ApRendererService { public renderHashtag(tag: string): IApHashtag { return { type: 'Hashtag', - href: `${this.config.url}/tags/${encodeURIComponent(tag)}`, + href: `${this.config.webUrl}/tags/${encodeURIComponent(tag)}`, name: `#${tag}`, }; } @@ -318,7 +318,7 @@ export class ApRendererService { @bindThis public renderKey(user: MiLocalUser, key: MiUserKeypair, postfix?: string): IKey { return { - id: `${this.config.url}/users/${user.id}${postfix ?? '/publickey'}`, + id: `${this.config.webUrl}/users/${user.id}${postfix ?? '/publickey'}`, type: 'Key', owner: this.userEntityService.genLocalUserUri(user.id), publicKeyPem: createPublicKey(key.publicKey).export({ @@ -348,9 +348,9 @@ export class ApRendererService { const object: ILike = { type: 'Like', - id: `${this.config.url}/likes/${noteReaction.id}`, - actor: `${this.config.url}/users/${noteReaction.userId}`, - object: note.uri ? note.uri : `${this.config.url}/notes/${noteReaction.noteId}`, + id: `${this.config.webUrl}/likes/${noteReaction.id}`, + actor: `${this.config.webUrl}/users/${noteReaction.userId}`, + object: note.uri ? note.uri : `${this.config.webUrl}/notes/${noteReaction.noteId}`, content: isMastodon ? undefined : reaction, _misskey_reaction: isMastodon ? undefined : reaction, }; @@ -382,7 +382,7 @@ export class ApRendererService { const actor = this.userEntityService.getUserUri(src); const target = this.userEntityService.getUserUri(dst); return { - id: `${this.config.url}/moves/${src.id}/${dst.id}`, + id: `${this.config.webUrl}/moves/${src.id}/${dst.id}`, actor, type: 'Move', object: actor, @@ -414,7 +414,7 @@ export class ApRendererService { if (dive) { inReplyTo = await this.renderNote(inReplyToNote, inReplyToUser, false); } else { - inReplyTo = `${this.config.url}/notes/${inReplyToNote.id}`; + inReplyTo = `${this.config.webUrl}/notes/${inReplyToNote.id}`; } } } @@ -429,7 +429,7 @@ export class ApRendererService { const renote = await this.notesRepository.findOneBy({ id: note.renoteId }); if (renote) { - quote = renote.uri ? renote.uri : `${this.config.url}/notes/${renote.id}`; + quote = renote.uri ? renote.uri : `${this.config.webUrl}/notes/${renote.id}`; } } @@ -540,7 +540,7 @@ export class ApRendererService { const replies = isPublic ? await this.renderRepliesCollection(note.id) : undefined; return { - id: `${this.config.url}/notes/${note.id}`, + id: `${this.config.webUrl}/notes/${note.id}`, type: 'Note', attributedTo, summary: summary ?? undefined, @@ -608,9 +608,9 @@ export class ApRendererService { followers: `${id}/followers`, following: `${id}/following`, featured: `${id}/collections/featured`, - sharedInbox: `${this.config.url}/inbox`, - endpoints: { sharedInbox: `${this.config.url}/inbox` }, - url: `${this.config.url}/@${user.username}`, + sharedInbox: `${this.config.webUrl}/inbox`, + endpoints: { sharedInbox: `${this.config.webUrl}/inbox` }, + url: `${this.config.webUrl}/@${user.username}`, preferredUsername: user.username, name: user.name, summary: profile.description ? this.mfmService.toHtml(mfm.parse(profile.description)) : null, @@ -672,9 +672,9 @@ export class ApRendererService { id, inbox: `${id}/inbox`, outbox: `${id}/outbox`, - sharedInbox: `${this.config.url}/inbox`, - endpoints: { sharedInbox: `${this.config.url}/inbox` }, - url: `${this.config.url}/@${user.username}`, + sharedInbox: `${this.config.webUrl}/inbox`, + endpoints: { sharedInbox: `${this.config.webUrl}/inbox` }, + url: `${this.config.webUrl}/@${user.username}`, preferredUsername: user.username, publicKey: this.renderKey(user, keypair, '#main-key'), @@ -695,7 +695,7 @@ export class ApRendererService { public renderQuestion(user: { id: MiUser['id'] }, note: MiNote, poll: MiPoll): IQuestion { return { type: 'Question', - id: `${this.config.url}/questions/${note.id}`, + id: `${this.config.webUrl}/questions/${note.id}`, actor: this.userEntityService.genLocalUserUri(user.id), content: note.text ?? '', [poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({ @@ -752,7 +752,7 @@ export class ApRendererService { @bindThis public renderUpdate(object: string | IObject, user: { id: MiUser['id'] }): IUpdate { return { - id: `${this.config.url}/users/${user.id}#updates/${new Date().getTime()}`, + id: `${this.config.webUrl}/users/${user.id}#updates/${new Date().getTime()}`, actor: this.userEntityService.genLocalUserUri(user.id), type: 'Update', to: ['https://www.w3.org/ns/activitystreams#Public'], @@ -764,13 +764,13 @@ export class ApRendererService { @bindThis public renderVote(user: { id: MiUser['id'] }, vote: MiPollVote, note: MiNote, poll: MiPoll, pollOwner: MiRemoteUser): ICreate { return { - id: `${this.config.url}/users/${user.id}#votes/${vote.id}/activity`, + id: `${this.config.webUrl}/users/${user.id}#votes/${vote.id}/activity`, actor: this.userEntityService.genLocalUserUri(user.id), type: 'Create', to: [pollOwner.uri], published: new Date().toISOString(), object: { - id: `${this.config.url}/users/${user.id}#votes/${vote.id}`, + id: `${this.config.webUrl}/users/${user.id}#votes/${vote.id}`, type: 'Note', attributedTo: this.userEntityService.genLocalUserUri(user.id), to: [pollOwner.uri], @@ -783,7 +783,7 @@ export class ApRendererService { @bindThis public addContext<T extends IObject>(x: T): T & { '@context': any; id: string; } { if (typeof x === 'object' && x.id == null) { - x.id = `${this.config.url}/${randomUUID()}`; + x.id = `${this.config.webUrl}/${randomUUID()}`; } return Object.assign({ '@context': CONTEXT }, x as T & { id: string }); @@ -800,7 +800,7 @@ export class ApRendererService { const keypair = await this.userKeypairService.getUserKeypair(user.id); - activity = await this.jsonLdService.signRsaSignature2017(activity, keypair.privateKey, `${this.config.url}/users/${user.id}#main-key`); + activity = await this.jsonLdService.signRsaSignature2017(activity, keypair.privateKey, `${this.config.webUrl}/users/${user.id}#main-key`); return activity; } @@ -867,8 +867,8 @@ export class ApRendererService { return { type: 'OrderedCollection', - id: `${this.config.url}/notes/${noteId}/replies`, - first: `${this.config.url}/notes/${noteId}/replies?page=true`, + id: `${this.config.webUrl}/notes/${noteId}/replies`, + first: `${this.config.webUrl}/notes/${noteId}/replies?page=true`, totalItems: replyCount, }; } @@ -898,18 +898,18 @@ export class ApRendererService { .getRawMany<{ note_id: string, note_uri: string | null }>(); const hasNextPage = results.length >= limit; - const baseId = `${this.config.url}/notes/${noteId}/replies?page=true`; + const baseId = `${this.config.webUrl}/notes/${noteId}/replies?page=true`; return { type: 'OrderedCollectionPage', id: untilId == null ? baseId : `${baseId}&until_id=${untilId}`, - partOf: `${this.config.url}/notes/${noteId}/replies`, + partOf: `${this.config.webUrl}/notes/${noteId}/replies`, first: baseId, next: hasNextPage ? `${baseId}&until_id=${results.at(-1)?.note_id}` : undefined, totalItems: replyCount, orderedItems: results.map(r => { // Remote notes have a URI, local have just an ID. - return r.note_uri ?? `${this.config.url}/notes/${r.note_id}`; + return r.note_uri ?? `${this.config.webUrl}/notes/${r.note_id}`; }), }; } @@ -920,7 +920,7 @@ export class ApRendererService { if (isPureRenote(note)) { const renote = hint?.renote ?? note.renote ?? await this.notesRepository.findOneByOrFail({ id: note.renoteId }); - const apAnnounce = this.renderAnnounce(renote.uri ?? `${this.config.url}/notes/${renote.id}`, note); + const apAnnounce = this.renderAnnounce(renote.uri ?? `${this.config.webUrl}/notes/${renote.id}`, note); return this.addContext(apAnnounce); } diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts index 7669ce9669..cd92adc549 100644 --- a/packages/backend/src/core/activitypub/ApRequestService.ts +++ b/packages/backend/src/core/activitypub/ApRequestService.ts @@ -164,7 +164,7 @@ export class ApRequestService { const req = ApRequestCreator.createSignedPost({ key: { privateKeyPem: keypair.privateKey, - keyId: `${this.config.url}/users/${user.id}#main-key`, + keyId: `${this.config.webUrl}/users/${user.id}#main-key`, }, url, body, @@ -195,7 +195,7 @@ export class ApRequestService { const req = ApRequestCreator.createSignedGet({ key: { privateKeyPem: keypair.privateKey, - keyId: `${this.config.url}/users/${user.id}#main-key`, + keyId: `${this.config.webUrl}/users/${user.id}#main-key`, }, url, additionalHeaders: { diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index f1a2522c04..8870395a1b 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -252,7 +252,7 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown { if (cached) return cached; // URIがこのサーバーを指しているならデータベースからフェッチ - if (uri.startsWith(`${this.config.url}/`)) { + if (uri.startsWith(`${this.config.webUrl}/`) || uri.startsWith(`${this.config.localUrl}/`)) { const id = uri.split('/').pop(); const u = await this.usersRepository.findOneBy({ id }) as MiLocalUser | null; if (u) this.cacheService.uriPersonCache.set(uri, u); @@ -327,7 +327,8 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown { if (typeof uri !== 'string') throw new UnrecoverableError(`failed to create user ${uri}: input is not string`); const host = this.utilityService.punyHost(uri); - if (host === this.utilityService.toPuny(this.config.host)) { + if ((host === this.utilityService.toPuny(this.config.localHost)) || + (host === this.utilityService.toPuny(this.config.webHost))) { throw new UnrecoverableError(`failed to create user ${uri}: URI is local`); } diff --git a/packages/backend/src/core/entities/DriveFileEntityService.ts b/packages/backend/src/core/entities/DriveFileEntityService.ts index c485555f90..06b20928a1 100644 --- a/packages/backend/src/core/entities/DriveFileEntityService.ts +++ b/packages/backend/src/core/entities/DriveFileEntityService.ts @@ -119,7 +119,7 @@ export class DriveFileEntityService { const key = file.webpublicAccessKey; if (key && !key.match('/')) { // 古いものはここにオブジェクトストレージキーが入ってるので除外 - const url = `${this.config.url}/files/${key}`; + const url = `${this.config.webUrl}/files/${key}`; if (mode === 'avatar') return this.getProxiedUrl(file.uri, 'avatar'); return url; } diff --git a/packages/backend/src/core/entities/MetaEntityService.ts b/packages/backend/src/core/entities/MetaEntityService.ts index 294187feba..79e9c90528 100644 --- a/packages/backend/src/core/entities/MetaEntityService.ts +++ b/packages/backend/src/core/entities/MetaEntityService.ts @@ -73,7 +73,7 @@ export class MetaEntityService { name: instance.name, shortName: instance.shortName, - uri: this.config.url, + uri: this.config.webUrl, description: instance.description, langs: instance.langs, tosUrl: instance.termsOfServiceUrl, diff --git a/packages/backend/src/core/entities/NoteEntityService.ts b/packages/backend/src/core/entities/NoteEntityService.ts index 4248fde77f..03f7ced909 100644 --- a/packages/backend/src/core/entities/NoteEntityService.ts +++ b/packages/backend/src/core/entities/NoteEntityService.ts @@ -833,6 +833,6 @@ export class NoteEntityService implements OnModuleInit { @bindThis public genLocalNoteUri(noteId: string): string { - return `${this.config.url}/notes/${noteId}`; + return `${this.config.webUrl}/notes/${noteId}`; } } diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 638eaac16f..c88632b856 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -400,10 +400,10 @@ export class UserEntityService implements OnModuleInit { @bindThis public getIdenticonUrl(user: MiUser): string { - if ((user.host == null || user.host === this.config.host) && user.username.includes('.') && this.meta.iconUrl) { // ローカルのシステムアカウントの場合 + if ((user.host == null || user.host === this.config.localHost) && user.username.includes('.') && this.meta.iconUrl) { // ローカルのシステムアカウントの場合 return this.meta.iconUrl; } else { - return `${this.config.url}/identicon/${user.username.toLowerCase()}@${user.host ?? this.config.host}`; + return `${this.config.webUrl}/identicon/${user.username.toLowerCase()}@${user.host ?? this.config.localHost}`; } } @@ -415,7 +415,7 @@ export class UserEntityService implements OnModuleInit { @bindThis public genLocalUserUri(userId: string): string { - return `${this.config.url}/users/${userId}`; + return `${this.config.webUrl}/users/${userId}`; } public async pack<S extends 'MeDetailed' | 'UserDetailedNotMe' | 'UserDetailed' | 'UserLite' = 'UserLite'>( @@ -531,7 +531,7 @@ export class UserEntityService implements OnModuleInit { ...announcement, })) : null; - const checkHost = user.host == null ? this.config.host : user.host; + const checkHost = user.host == null ? this.config.localHost : user.host; const notificationsInfo = isMe && isDetailed ? await this.getNotificationsInfo(user.id) : null; let fetchPoliciesPromise: Promise<RolePolicies> | null = null; diff --git a/packages/backend/src/queue/processors/ExportAccountDataProcessorService.ts b/packages/backend/src/queue/processors/ExportAccountDataProcessorService.ts index 58d542635f..1410874f02 100644 --- a/packages/backend/src/queue/processors/ExportAccountDataProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportAccountDataProcessorService.ts @@ -125,7 +125,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeUser(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","user":[`); + await writeUser(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","user":[`); // eslint-disable-next-line @typescript-eslint/no-unused-vars const { host, uri, sharedInbox, followersUri, lastFetchedAt, inbox, ...userTrimmed } = user; @@ -160,7 +160,7 @@ export class ExportAccountDataProcessorService { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { emailVerifyCode, twoFactorBackupSecret, twoFactorSecret, password, twoFactorTempSecret, userHost, ...profileTrimmed } = profile; - await writeProfile(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","profile":[`); + await writeProfile(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","profile":[`); await writeProfile(JSON.stringify(profileTrimmed)); @@ -191,7 +191,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeIPs(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","ips":[`); + await writeIPs(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","ips":[`); for (const signin of signins) { // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -226,7 +226,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeNotes(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","notes":[`); + await writeNotes(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","notes":[`); let noteCursor: MiNote['id'] | null = null; let exportedNotesCount = 0; @@ -287,7 +287,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeFollowing(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","followings":[`); + await writeFollowing(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","followings":[`); let followingsCursor: MiFollowing['id'] | null = null; let exportedFollowingsCount = 0; @@ -357,7 +357,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeFollowers(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","followers":[`); + await writeFollowers(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","followers":[`); let followersCursor: MiFollowing['id'] | null = null; let exportedFollowersCount = 0; @@ -420,7 +420,7 @@ export class ExportAccountDataProcessorService { fs.mkdirSync(`${path}/files`); - await writeDrive(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","drive":[`); + await writeDrive(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","drive":[`); const driveFiles = await this.driveFilesRepository.find({ where: { userId: user.id } }); @@ -476,7 +476,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeMuting(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","mutings":[`); + await writeMuting(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","mutings":[`); let exportedMutingCount = 0; let mutingCursor: MiMuting['id'] | null = null; @@ -539,7 +539,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeBlocking(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","blockings":[`); + await writeBlocking(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","blockings":[`); let exportedBlockingCount = 0; let blockingCursor: MiBlocking['id'] | null = null; @@ -601,7 +601,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeFavorite(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","favorites":[`); + await writeFavorite(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","favorites":[`); let exportedFavoritesCount = 0; let favoriteCursor: MiNoteFavorite['id'] | null = null; @@ -662,7 +662,7 @@ export class ExportAccountDataProcessorService { }); }; - await writeAntenna(`{"metaVersion":1,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","antennas":[`); + await writeAntenna(`{"metaVersion":1,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","antennas":[`); const antennas = await this.antennasRepository.findBy({ userId: user.id }); diff --git a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts index b8f208bbfc..d3edc7890b 100644 --- a/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts +++ b/packages/backend/src/queue/processors/ExportCustomEmojisProcessorService.ts @@ -76,7 +76,7 @@ export class ExportCustomEmojisProcessorService { }); }; - await writeMeta(`{"metaVersion":2,"host":"${this.config.host}","exportedAt":"${new Date().toString()}","emojis":[`); + await writeMeta(`{"metaVersion":2,"host":"${this.config.webHost}","exportedAt":"${new Date().toString()}","emojis":[`); const customEmojis = await this.emojisRepository.find({ where: { diff --git a/packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts b/packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts index f9fcd1e928..a3c0c47162 100644 --- a/packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/SystemWebhookDeliverProcessorService.ts @@ -42,13 +42,13 @@ export class SystemWebhookDeliverProcessorService { method: 'POST', headers: { 'User-Agent': 'Misskey-Hooks', - 'X-Misskey-Host': this.config.host, + 'X-Misskey-Host': this.config.webHost, 'X-Misskey-Hook-Id': job.data.webhookId, 'X-Misskey-Hook-Secret': job.data.secret, 'Content-Type': 'application/json', }, body: JSON.stringify({ - server: this.config.url, + server: this.config.webUrl, hookId: job.data.webhookId, eventId: job.data.eventId, createdAt: job.data.createdAt, diff --git a/packages/backend/src/queue/processors/UserWebhookDeliverProcessorService.ts b/packages/backend/src/queue/processors/UserWebhookDeliverProcessorService.ts index 0208ce6038..411f6023a8 100644 --- a/packages/backend/src/queue/processors/UserWebhookDeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/UserWebhookDeliverProcessorService.ts @@ -41,13 +41,13 @@ export class UserWebhookDeliverProcessorService { method: 'POST', headers: { 'User-Agent': 'Misskey-Hooks', - 'X-Misskey-Host': this.config.host, + 'X-Misskey-Host': this.config.webHost, 'X-Misskey-Hook-Id': job.data.webhookId, 'X-Misskey-Hook-Secret': job.data.secret, 'Content-Type': 'application/json', }, body: JSON.stringify({ - server: this.config.url, + server: this.config.webUrl, hookId: job.data.webhookId, userId: job.data.userId, eventId: job.data.eventId, diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 27d25d2152..9a8309b41c 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -114,7 +114,7 @@ export class ActivityPubServerService { private async packActivity(note: MiNote, author: MiUser): Promise<ICreate | IAnnounce> { if (isRenote(note) && !isQuote(note)) { const renote = await this.notesRepository.findOneByOrFail({ id: note.renoteId }); - return this.apRendererService.renderAnnounce(renote.uri ? renote.uri : `${this.config.url}/notes/${renote.id}`, note); + return this.apRendererService.renderAnnounce(renote.uri ? renote.uri : `${this.config.webUrl}/notes/${renote.id}`, note); } return this.apRendererService.renderCreate(await this.apRendererService.renderNote(note, author, false), note); @@ -196,7 +196,7 @@ export class ActivityPubServerService { const logPrefix = `${request.id} ${request.url} (by ${request.headers['user-agent']}) claims to be from ${keyHost}:`; - if (signature.params.headers.indexOf('host') === -1 || request.headers.host !== this.config.host) { + if (signature.params.headers.indexOf('host') === -1 || (request.headers.host !== this.config.localHost && request.headers.host !== this.config.webHost)) { // no destination host, or not us: refuse return `${logPrefix} no destination host, or not us: refuse`; } @@ -292,7 +292,7 @@ export class ActivityPubServerService { } if (signature.params.headers.indexOf('host') === -1 - || request.headers.host !== this.config.host) { + || (request.headers.host !== this.config.localHost && request.headers.host !== this.config.webHost)) { // Host not specified or not match. reply.code(401); return; @@ -394,7 +394,7 @@ export class ActivityPubServerService { //#endregion const limit = 10; - const partOf = `${this.config.url}/users/${userId}/followers`; + const partOf = `${this.config.webUrl}/users/${userId}/followers`; if (page) { const query = { @@ -491,7 +491,7 @@ export class ActivityPubServerService { //#endregion const limit = 10; - const partOf = `${this.config.url}/users/${userId}/following`; + const partOf = `${this.config.webUrl}/users/${userId}/following`; if (page) { const query = { @@ -576,7 +576,7 @@ export class ActivityPubServerService { const renderedNotes = await Promise.all(pinnedNotes.map(note => this.apRendererService.renderNote(note, user))); const rendered = this.apRendererService.renderOrderedCollection( - `${this.config.url}/users/${userId}/collections/featured`, + `${this.config.webUrl}/users/${userId}/collections/featured`, renderedNotes.length, undefined, undefined, @@ -635,7 +635,7 @@ export class ActivityPubServerService { } const limit = 20; - const partOf = `${this.config.url}/users/${userId}/outbox`; + const partOf = `${this.config.webUrl}/users/${userId}/outbox`; if (page) { const notes = this.meta.enableFanoutTimeline ? await this.fanoutTimelineEndpointService.getMiNotes({ diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts index 0910c0d36b..2931c785f4 100644 --- a/packages/backend/src/server/FileServerService.ts +++ b/packages/backend/src/server/FileServerService.ts @@ -93,7 +93,7 @@ export class FileServerService { .catch(err => this.errorHandler(request, reply, err)); }); fastify.get<{ Params: { key: string; } }>('/files/:key/*', async (request, reply) => { - return await reply.redirect(`${this.config.url}/files/${request.params.key}`, 301); + return await reply.redirect(`${this.config.webUrl}/files/${request.params.key}`, 301); }); done(); }); @@ -524,8 +524,8 @@ export class FileServerService { | '404' | '204' > { - if (url.startsWith(`${this.config.url}/files/`)) { - const key = url.replace(`${this.config.url}/files/`, '').split('/').shift(); + if (url.startsWith(`${this.config.webUrl}/files/`)) { + const key = url.replace(`${this.config.webUrl}/files/`, '').split('/').shift(); if (!key) throw new StatusError(`Invalid file URL ${url}`, 400, 'Invalid file url'); return await this.getFileFromKey(key); diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index 55e8827696..7210d824ce 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -37,10 +37,10 @@ export class NodeinfoServerService { public getLinks() { return [{ rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1', - href: this.config.url + nodeinfo2_1path, + href: this.config.webUrl + nodeinfo2_1path, }, { rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0', - href: this.config.url + nodeinfo2_0path, + href: this.config.webUrl + nodeinfo2_0path, }]; } diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts index 77b4519570..0d8fc9adbe 100644 --- a/packages/backend/src/server/ServerService.ts +++ b/packages/backend/src/server/ServerService.ts @@ -85,7 +85,7 @@ export class ServerService implements OnApplicationShutdown { // HSTS // 6months (15552000sec) - if (this.config.url.startsWith('https') && !this.config.disableHsts) { + if (this.config.webUrl.startsWith('https') && !this.config.disableHsts) { fastify.addHook('onRequest', (request, reply, done) => { reply.header('strict-transport-security', 'max-age=15552000; preload'); done(); @@ -126,7 +126,7 @@ export class ServerService implements OnApplicationShutdown { } const effectiveLocation = process.env.NODE_ENV === 'production' ? location : location.replace(/^http:\/\//, 'https://'); - if (effectiveLocation.startsWith(`https://${this.config.host}/`)) { + if (effectiveLocation.startsWith(`https://${this.config.webHost}/`)) { done(); return; } @@ -216,7 +216,7 @@ export class ServerService implements OnApplicationShutdown { const user = await this.usersRepository.findOne({ where: { usernameLower: username.toLowerCase(), - host: (host == null) || (host === this.config.host) ? IsNull() : host, + host: (host == null) || (host === this.config.localHost) ? IsNull() : host, isSuspended: false, }, }); diff --git a/packages/backend/src/server/WellKnownServerService.ts b/packages/backend/src/server/WellKnownServerService.ts index f48310c50f..fa6e095fd2 100644 --- a/packages/backend/src/server/WellKnownServerService.ts +++ b/packages/backend/src/server/WellKnownServerService.ts @@ -78,7 +78,7 @@ export class WellKnownServerService { return XRD({ element: 'Link', attributes: { rel: 'lrdd', type: xrd, - template: `${this.config.url}${webFingerPath}?resource={uri}`, + template: `${this.config.webUrl}${webFingerPath}?resource={uri}`, } }); }); @@ -93,7 +93,7 @@ export class WellKnownServerService { links: [{ rel: 'lrdd', type: jrd, - template: `${this.config.url}${webFingerPath}?resource={uri}`, + template: `${this.config.webUrl}${webFingerPath}?resource={uri}`, }], }; }); @@ -129,15 +129,15 @@ fastify.get('/.well-known/change-password', async (request, reply) => { }); const generateQuery = (resource: string): FindOptionsWhere<MiUser> | number => - resource.startsWith(`${this.config.url.toLowerCase()}/users/`) ? + resource.startsWith(`${this.config.webUrl.toLowerCase()}/users/`) ? fromId(resource.split('/').pop()!) : fromAcct(Acct.parse( - resource.startsWith(`${this.config.url.toLowerCase()}/@`) ? resource.split('/').pop()! : + resource.startsWith(`${this.config.localUrl.toLowerCase()}/@`) ? resource.split('/').pop()! : resource.startsWith('acct:') ? resource.slice('acct:'.length) : resource)); const fromAcct = (acct: Acct.Acct): FindOptionsWhere<MiUser> | number => - !acct.host || acct.host === this.config.host.toLowerCase() ? { + !acct.host || acct.host === this.config.localHost.toLowerCase() || acct.host === this.config.webHost.toLowerCase() ? { usernameLower: acct.username.toLowerCase(), host: IsNull(), isSuspended: false, @@ -162,8 +162,8 @@ fastify.get('/.well-known/change-password', async (request, reply) => { return; } - const subject = `acct:${user.username}@${this.config.host}`; - const profileLink = `${this.config.url}/@${user.username}`; + const subject = `acct:${user.username}@${this.config.localHost}`; + const profileLink = `${this.config.webUrl}/@${user.username}`; const self = { rel: 'self', type: 'application/activity+json', @@ -176,7 +176,7 @@ fastify.get('/.well-known/change-password', async (request, reply) => { }; const subscribe = { rel: 'http://ostatus.org/schema/1.0/subscribe', - template: `${this.config.url}/authorize-follow?acct={uri}`, + template: `${this.config.webUrl}/authorize-follow?acct={uri}`, }; vary(reply.raw, 'Accept'); diff --git a/packages/backend/src/server/api/SigninApiService.ts b/packages/backend/src/server/api/SigninApiService.ts index a53fec88d0..e6c918d6f4 100644 --- a/packages/backend/src/server/api/SigninApiService.ts +++ b/packages/backend/src/server/api/SigninApiService.ts @@ -88,7 +88,7 @@ export class SigninApiService { }>, reply: FastifyReply, ) { - reply.header('Access-Control-Allow-Origin', this.config.url); + reply.header('Access-Control-Allow-Origin', this.config.webUrl); reply.header('Access-Control-Allow-Credentials', 'true'); const body = request.body; diff --git a/packages/backend/src/server/api/SigninWithPasskeyApiService.ts b/packages/backend/src/server/api/SigninWithPasskeyApiService.ts index 38886f8876..a2e0a43c15 100644 --- a/packages/backend/src/server/api/SigninWithPasskeyApiService.ts +++ b/packages/backend/src/server/api/SigninWithPasskeyApiService.ts @@ -62,7 +62,7 @@ export class SigninWithPasskeyApiService { }>, reply: FastifyReply, ) { - reply.header('Access-Control-Allow-Origin', this.config.url); + reply.header('Access-Control-Allow-Origin', this.config.webUrl); reply.header('Access-Control-Allow-Credentials', 'true'); const body = request.body; diff --git a/packages/backend/src/server/api/SignupApiService.ts b/packages/backend/src/server/api/SignupApiService.ts index 81e3a5b706..3d2b003796 100644 --- a/packages/backend/src/server/api/SignupApiService.ts +++ b/packages/backend/src/server/api/SignupApiService.ts @@ -215,7 +215,7 @@ export class SignupApiService { reason: reason, }); - const link = `${this.config.url}/signup-complete/${code}`; + const link = `${this.config.webUrl}/signup-complete/${code}`; this.emailService.sendEmail(emailAddress!, 'Signup', `To complete signup, please click this link:<br><a href="${link}">${link}</a>`, diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index fe8ca012b2..4f9187f8ca 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -644,7 +644,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- version: this.config.version, name: instance.name, shortName: instance.shortName, - uri: this.config.url, + uri: this.config.webUrl, description: instance.description, langs: instance.langs, tosUrl: instance.termsOfServiceUrl, 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 6fde3a90a7..0d47269c1c 100644 --- a/packages/backend/src/server/api/endpoints/i/2fa/register.ts +++ b/packages/backend/src/server/api/endpoints/i/2fa/register.ts @@ -101,7 +101,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- secret, digits: 6, label: me.username, - issuer: this.config.host, + issuer: this.config.webHost, }); const url = totp.toString(); const qr = await QRCode.toDataURL(url); @@ -111,7 +111,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- url, secret: secret.base32, label: me.username, - issuer: this.config.host, + issuer: this.config.webHost, }; }); } 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 dc07556760..46bfa662d6 100644 --- a/packages/backend/src/server/api/endpoints/i/update-email.ts +++ b/packages/backend/src/server/api/endpoints/i/update-email.ts @@ -131,7 +131,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- emailVerifyCode: code, }); - const link = `${this.config.url}/verify-email/${code}`; + const link = `${this.config.webUrl}/verify-email/${code}`; this.emailService.sendEmail(ps.email, 'Email verification', `To verify email, please click this link:<br><a href="${link}">${link}</a>`, diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index 65dcf6301f..fa417b5fa0 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -605,7 +605,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const profileUrls = [ this.userEntityService.genLocalUserUri(user.id), - `${this.config.url}/@${user.username}`, + `${this.config.webUrl}/@${user.username}`, ]; const verifiedLinks = await verifyFieldLinks(newFields, profileUrls, this.httpRequestService); @@ -651,7 +651,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- const { window } = new JSDOM(html); const doc: Document = window.document; - const myLink = `${this.config.url}/@${user.username}`; + const myLink = `${this.config.webUrl}/@${user.username}`; const aEls = Array.from(doc.getElementsByTagName('a')); const linkEls = Array.from(doc.getElementsByTagName('link')); 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 86fe6a2e6e..9f4acec44e 100644 --- a/packages/backend/src/server/api/endpoints/request-reset-password.ts +++ b/packages/backend/src/server/api/endpoints/request-reset-password.ts @@ -89,7 +89,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint- token, }); - const link = `${this.config.url}/reset-password/${token}`; + const link = `${this.config.webUrl}/reset-password/${token}`; this.emailService.sendEmail(ps.email, 'Password reset requested', `To reset password, please click this link:<br><a href="${link}">${link}</a>`, diff --git a/packages/backend/src/server/api/mastodon/MastodonConverters.ts b/packages/backend/src/server/api/mastodon/MastodonConverters.ts index df8d68042a..02fa9ac85e 100644 --- a/packages/backend/src/server/api/mastodon/MastodonConverters.ts +++ b/packages/backend/src/server/api/mastodon/MastodonConverters.ts @@ -72,7 +72,7 @@ export class MastodonConverters { private encode(u: MiUser, m: IMentionedRemoteUsers): MastodonEntity.Mention { let acct = u.username; - let acctUrl = `https://${u.host || this.config.host}/@${u.username}`; + let acctUrl = `https://${u.host || this.config.webHost}/@${u.username}`; let url: string | null = null; if (u.host) { const info = m.find(r => r.username === u.username && r.host === u.host); @@ -150,7 +150,7 @@ export class MastodonConverters { public async convertAccount(account: Entity.Account | MiUser): Promise<MastodonEntity.Account> { const user = await this.getUser(account.id); const profile = await this.userProfilesRepository.findOneBy({ userId: user.id }); - const emojis = await this.customEmojiService.populateEmojis(user.emojis, user.host ? user.host : this.config.host); + const emojis = await this.customEmojiService.populateEmojis(user.emojis, user.host ? user.host : this.config.localHost); const emoji: Entity.Emoji[] = []; Object.entries(emojis).forEach(entry => { const [key, value] = entry; @@ -162,10 +162,10 @@ export class MastodonConverters { category: undefined, }); }); - const fqn = `${user.username}@${user.host ?? this.config.hostname}`; + const fqn = `${user.username}@${user.host ?? this.config.localHostname}`; let acct = user.username; - let acctUrl = `https://${user.host || this.config.host}/@${user.username}`; - const acctUri = `https://${this.config.host}/users/${user.id}`; + let acctUrl = `https://${user.host || this.config.webHost}/@${user.username}`; + const acctUri = `https://${this.config.webHost}/users/${user.id}`; if (user.host) { acct = `${user.username}@${user.host}`; acctUrl = `https://${user.host}/@${user.username}`; @@ -228,7 +228,7 @@ export class MastodonConverters { const isQuote = renote && (edit.cw || edit.newText || edit.fileIds.length > 0 || note.replyId); const quoteUri = isQuote - ? renote.url ?? renote.uri ?? `${this.config.url}/notes/${renote.id}` + ? renote.url ?? renote.uri ?? `${this.config.webUrl}/notes/${renote.id}` : null; const item = { @@ -258,7 +258,7 @@ export class MastodonConverters { const noteUser = hints?.user ?? note.user ?? await this.getUser(status.account.id); const mentionedRemoteUsers = JSON.parse(note.mentionedRemoteUsers); - const emojis = await this.customEmojiService.populateEmojis(note.emojis, noteUser.host ? noteUser.host : this.config.host); + const emojis = await this.customEmojiService.populateEmojis(note.emojis, noteUser.host ? noteUser.host : this.config.localHost); const emoji: Entity.Emoji[] = []; Object.entries(emojis).forEach(entry => { const [key, value] = entry; @@ -280,7 +280,7 @@ export class MastodonConverters { const tags = note.tags.map(tag => { return { name: tag, - url: `${this.config.url}/tags/${tag}`, + url: `${this.config.webUrl}/tags/${tag}`, } as Entity.Tag; }); @@ -291,7 +291,7 @@ export class MastodonConverters { const quoteUri = Promise.resolve(renote).then(renote => { if (!renote || !isQuote) return null; - return renote.url ?? renote.uri ?? `${this.config.url}/notes/${renote.id}`; + return renote.url ?? renote.uri ?? `${this.config.webUrl}/notes/${renote.id}`; }); const text = note.text; @@ -306,8 +306,8 @@ export class MastodonConverters { // noinspection ES6MissingAwait return await awaitAll({ id: note.id, - uri: note.uri ?? `https://${this.config.host}/notes/${note.id}`, - url: note.url ?? note.uri ?? `https://${this.config.host}/notes/${note.id}`, + uri: note.uri ?? `https://${this.config.webHost}/notes/${note.id}`, + url: note.url ?? note.uri ?? `https://${this.config.webHost}/notes/${note.id}`, account: convertedAccount, in_reply_to_id: note.replyId, in_reply_to_account_id: note.replyUserId, diff --git a/packages/backend/src/server/api/mastodon/endpoints/instance.ts b/packages/backend/src/server/api/mastodon/endpoints/instance.ts index cfca5b1350..178ecc91e8 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/instance.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/instance.ts @@ -39,7 +39,7 @@ export class ApiInstanceMastodon { const instance = data.data; const response: MastodonEntity.Instance = { - uri: this.config.host, + uri: this.config.webHost, title: this.meta.name || 'Sharkey', description: this.meta.description || 'This is a vanilla Sharkey Instance. It doesn\'t seem to have a description.', email: instance.email || '', diff --git a/packages/backend/src/server/oauth/OAuth2ProviderService.ts b/packages/backend/src/server/oauth/OAuth2ProviderService.ts index 01ee451297..45d24686de 100644 --- a/packages/backend/src/server/oauth/OAuth2ProviderService.ts +++ b/packages/backend/src/server/oauth/OAuth2ProviderService.ts @@ -62,9 +62,9 @@ export class OAuth2ProviderService { // https://indieauth.spec.indieweb.org/#indieauth-server-metadata public generateRFC8414() { return { - issuer: this.config.url, - authorization_endpoint: new URL('/oauth/authorize', this.config.url), - token_endpoint: new URL('/oauth/token', this.config.url), + issuer: this.config.webUrl, + authorization_endpoint: new URL('/oauth/authorize', this.config.webUrl), + token_endpoint: new URL('/oauth/token', this.config.webUrl), scopes_supported: kinds, response_types_supported: ['code'], grant_types_supported: ['authorization_code'], @@ -80,9 +80,9 @@ export class OAuth2ProviderService { // https://indieauth.spec.indieweb.org/#indieauth-server-metadata /* fastify.get('/.well-known/oauth-authorization-server', async (_request, reply) => { reply.send({ - issuer: this.config.url, - authorization_endpoint: new URL('/oauth/authorize', this.config.url), - token_endpoint: new URL('/oauth/token', this.config.url), + issuer: this.config.webUrl, + authorization_endpoint: new URL('/oauth/authorize', this.config.webUrl), + token_endpoint: new URL('/oauth/token', this.config.webUrl), scopes_supported: kinds, response_types_supported: ['code'], grant_types_supported: ['authorization_code'], diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index c40d042fa4..2df92e4607 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -150,10 +150,10 @@ export class ClientServerService { let manifest = { // 空文字列の場合右辺を使いたいため // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - 'short_name': this.meta.shortName || this.meta.name || this.config.host, + 'short_name': this.meta.shortName || this.meta.name || this.config.webHost, // 空文字列の場合右辺を使いたいため // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - 'name': this.meta.name || this.config.host, + 'name': this.meta.name || this.config.webHost, 'start_url': '/', 'display': 'standalone', 'background_color': '#313a42', @@ -213,7 +213,8 @@ export class ClientServerService { serverErrorImageUrl: meta.serverErrorImageUrl ?? '/client-assets/status/error.png', infoImageUrl: meta.infoImageUrl ?? '/client-assets/status/nothinghere.png', notFoundImageUrl: meta.notFoundImageUrl ?? '/client-assets/status/missingpage.webp', - instanceUrl: this.config.url, + instanceUrl: this.config.webUrl, + localUrl: this.config.localUrl, randomMOTD: this.config.customMOTD ? this.config.customMOTD[Math.floor(Math.random() * this.config.customMOTD.length)] : undefined, metaJson: htmlSafeJsonStringify(await this.metaEntityService.packDetailed(meta)), now: Date.now(), @@ -441,8 +442,8 @@ export class ClientServerService { content += `<ShortName>${name}</ShortName>`; content += `<Description>${name} Search</Description>`; content += '<InputEncoding>UTF-8</InputEncoding>'; - content += `<Image width="16" height="16" type="image/x-icon">${this.config.url}/favicon.ico</Image>`; - content += `<Url type="text/html" template="${this.config.url}/search?q={searchTerms}"/>`; + content += `<Image width="16" height="16" type="image/x-icon">${this.config.webUrl}/favicon.ico</Image>`; + content += `<Url type="text/html" template="${this.config.webUrl}/search?q={searchTerms}"/>`; content += '</OpenSearchDescription>'; reply.header('Content-Type', 'application/opensearchdescription+xml'); @@ -455,7 +456,7 @@ export class ClientServerService { reply.header('Cache-Control', 'public, max-age=30'); return await reply.view('base', { img: this.meta.bannerUrl, - url: this.config.url, + url: this.config.webUrl, title: this.meta.name ?? 'Sharkey', desc: this.meta.description, customHead: this.config.customHtml.head, @@ -889,8 +890,8 @@ export class ClientServerService { return await reply.view('info-card', { version: this.config.version, - host: this.config.host, - url: this.config.url, + host: this.config.webHost, + url: this.config.webUrl, meta: this.meta, originalUsersCount: await this.usersRepository.countBy({ host: IsNull() }), originalNotesCount: await this.notesRepository.countBy({ userHost: IsNull() }), diff --git a/packages/backend/src/server/web/FeedService.ts b/packages/backend/src/server/web/FeedService.ts index a622ae7e34..e005a96732 100644 --- a/packages/backend/src/server/web/FeedService.ts +++ b/packages/backend/src/server/web/FeedService.ts @@ -42,7 +42,7 @@ export class FeedService { @bindThis public async packFeed(user: MiUser) { const author = { - link: `${this.config.url}/@${user.username}`, + link: `${this.config.webUrl}/@${user.username}`, name: user.name ?? user.username, }; @@ -60,7 +60,7 @@ export class FeedService { const feed = new Feed({ id: author.link, - title: `${author.name} (@${user.username}@${this.config.host})`, + title: `${author.name} (@${user.username}@${this.config.localHost})`, updated: notes.length !== 0 ? this.idService.parse(notes[0].id).date : undefined, generator: 'Sharkey', description: `${user.notesCount} Notes, ${profile.followingVisibility === 'public' ? user.followingCount : '?'} Following, ${profile.followersVisibility === 'public' ? user.followersCount : '?'} Followers${profile.description ? ` · ${profile.description}` : ''}`, @@ -92,7 +92,7 @@ export class FeedService { feed.addItem({ title: `New note by ${author.name}`, - link: `${this.config.url}/notes/${note.id}`, + link: `${this.config.webUrl}/notes/${note.id}`, date: this.idService.parse(note.id).date, description: note.cw ?? undefined, content: text ? this.mfmService.toHtml(mfmParse(text), JSON.parse(note.mentionedRemoteUsers)) ?? undefined : undefined, diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index 71a142fc6f..6168fb3602 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -477,7 +477,7 @@ export class UrlPreviewService { const url = URL.parse(summary.url); const acct = Acct.parse(summary.fediverseCreator); - if (acct.host?.toLowerCase() === this.config.host) { + if (acct.host?.toLowerCase() === this.config.localHost) { acct.host = null; } try { diff --git a/packages/backend/src/server/web/views/announcement.pug b/packages/backend/src/server/web/views/announcement.pug index 7a4052e8a4..2b35480c63 100644 --- a/packages/backend/src/server/web/views/announcement.pug +++ b/packages/backend/src/server/web/views/announcement.pug @@ -3,7 +3,7 @@ extends ./base block vars - const title = announcement.title; - const description = announcement.text.length > 100 ? announcement.text.slice(0, 100) + '…' : announcement.text; - - const url = `${config.url}/announcements/${announcement.id}`; + - const url = `${config.webUrl}/announcements/${announcement.id}`; block title = `${title} | ${instanceName}` diff --git a/packages/backend/src/server/web/views/base-embed.pug b/packages/backend/src/server/web/views/base-embed.pug index 6ef9281b8f..ef7d02e42a 100644 --- a/packages/backend/src/server/web/views/base-embed.pug +++ b/packages/backend/src/server/web/views/base-embed.pug @@ -15,6 +15,7 @@ html(class='embed') meta(name='theme-color-orig' content= themeColor || '#86b300') meta(property='og:site_name' content= instanceName || 'Sharkey') meta(property='instance_url' content= instanceUrl) + meta(property='local_url' content= localUrl) meta(name='viewport' content='width=device-width, initial-scale=1') meta(name='format-detection' content='telephone=no,date=no,address=no,email=no,url=no') link(rel='icon' href= icon || '/favicon.ico') diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug index d9d750281d..0bd6788a8d 100644 --- a/packages/backend/src/server/web/views/base.pug +++ b/packages/backend/src/server/web/views/base.pug @@ -2,7 +2,7 @@ block vars block loadClientEntry - const entry = config.frontendEntry; - - const baseUrl = config.url; + - const baseUrl = config.webUrl; doctype html @@ -32,6 +32,7 @@ html meta(name='theme-color-orig' content= themeColor || '#86b300') meta(property='og:site_name' content= instanceName || 'Sharkey') meta(property='instance_url' content= instanceUrl) + meta(property='local_url' content= localUrl) meta(name='viewport' content='width=device-width, initial-scale=1') meta(name='format-detection' content='telephone=no,date=no,address=no,email=no,url=no') link(rel='icon' href= icon || '/favicon.ico') diff --git a/packages/backend/src/server/web/views/channel.pug b/packages/backend/src/server/web/views/channel.pug index c514025e0b..530d56b51f 100644 --- a/packages/backend/src/server/web/views/channel.pug +++ b/packages/backend/src/server/web/views/channel.pug @@ -2,7 +2,7 @@ extends ./base block vars - const title = channel.name; - - const url = `${config.url}/channels/${channel.id}`; + - const url = `${config.webUrl}/channels/${channel.id}`; block title = `${title} | ${instanceName}` diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug index 5a0018803a..b6f2b02599 100644 --- a/packages/backend/src/server/web/views/clip.pug +++ b/packages/backend/src/server/web/views/clip.pug @@ -3,7 +3,7 @@ extends ./base block vars - const user = clip.user; - const title = clip.name; - - const url = `${config.url}/clips/${clip.id}`; + - const url = `${config.webUrl}/clips/${clip.id}`; block title = `${title} | ${instanceName}` diff --git a/packages/backend/src/server/web/views/flash.pug b/packages/backend/src/server/web/views/flash.pug index 1549aa7906..22961c6dcd 100644 --- a/packages/backend/src/server/web/views/flash.pug +++ b/packages/backend/src/server/web/views/flash.pug @@ -3,7 +3,7 @@ extends ./base block vars - const user = flash.user; - const title = flash.title; - - const url = `${config.url}/play/${flash.id}`; + - const url = `${config.webUrl}/play/${flash.id}`; block title = `${title} | ${instanceName}` diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug index 9ae25d9ac8..4ed44d0a4b 100644 --- a/packages/backend/src/server/web/views/gallery-post.pug +++ b/packages/backend/src/server/web/views/gallery-post.pug @@ -3,7 +3,7 @@ extends ./base block vars - const user = post.user; - const title = post.title; - - const url = `${config.url}/gallery/${post.id}`; + - const url = `${config.webUrl}/gallery/${post.id}`; block title = `${title} | ${instanceName}` diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug index 53cff6bcd3..9b755f60a2 100644 --- a/packages/backend/src/server/web/views/note.pug +++ b/packages/backend/src/server/web/views/note.pug @@ -3,7 +3,7 @@ extends ./base block vars - const user = note.user; - const title = user.name ? `${user.name} (@${user.username}${user.host ? `@${user.host}` : ''})` : `@${user.username}${user.host ? `@${user.host}` : ''}`; - - const url = `${config.url}/notes/${note.id}`; + - const url = `${config.webUrl}/notes/${note.id}`; - const isRenote = note.renote && note.text == null && note.fileIds.length == 0 && note.poll == null; - const images = note.cw ? [] : (note.files || []).filter(file => file.type.startsWith('image/') && !file.isSensitive) - const videos = note.cw ? [] : (note.files || []).filter(file => file.type.startsWith('video/') && !file.isSensitive) @@ -52,9 +52,9 @@ block meta meta(name='twitter:creator' content=`@${user.twitter.screenName}`) if note.prev - link(rel='prev' href=`${config.url}/notes/${note.prev}`) + link(rel='prev' href=`${config.webUrl}/notes/${note.prev}`) if note.next - link(rel='next' href=`${config.url}/notes/${note.next}`) + link(rel='next' href=`${config.webUrl}/notes/${note.next}`) if !user.host link(rel='alternate' href=url type='application/activity+json') diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug index 03c50eca8a..fcd54fd05c 100644 --- a/packages/backend/src/server/web/views/page.pug +++ b/packages/backend/src/server/web/views/page.pug @@ -3,7 +3,7 @@ extends ./base block vars - const user = page.user; - const title = page.title; - - const url = `${config.url}/@${user.username}/pages/${page.name}`; + - const url = `${config.webUrl}/@${user.username}/pages/${page.name}`; block title = `${title} | ${instanceName}` diff --git a/packages/backend/src/server/web/views/reversi-game.pug b/packages/backend/src/server/web/views/reversi-game.pug index 0b5ffb2bb0..6e0cd32e7f 100644 --- a/packages/backend/src/server/web/views/reversi-game.pug +++ b/packages/backend/src/server/web/views/reversi-game.pug @@ -4,7 +4,7 @@ block vars - const user1 = game.user1; - const user2 = game.user2; - const title = `${user1.username} vs ${user2.username}`; - - const url = `${config.url}/reversi/g/${game.id}`; + - const url = `${config.webUrl}/reversi/g/${game.id}`; block title = `${title} | ${instanceName}` diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug index 2b0a7bab5c..7a023e255e 100644 --- a/packages/backend/src/server/web/views/user.pug +++ b/packages/backend/src/server/web/views/user.pug @@ -2,7 +2,7 @@ extends ./base block vars - const title = user.name ? `${user.name} (@${user.username}${user.host ? `@${user.host}` : ''})` : `@${user.username}${user.host ? `@${user.host}` : ''}`; - - const url = `${config.url}/@${(user.host ? `${user.username}@${user.host}` : user.username)}`; + - const url = `${config.webUrl}/@${(user.host ? `${user.username}@${user.host}` : user.username)}`; block title = `${title} | ${instanceName}` @@ -33,7 +33,7 @@ block meta if !sub if !user.host - link(rel='alternate' href=`${config.url}/users/${user.id}` type='application/activity+json') + link(rel='alternate' href=`${config.webUrl}/users/${user.id}` type='application/activity+json') if user.uri link(rel='alternate' href=user.uri type='application/activity+json') if profile.url diff --git a/packages/backend/test/e2e/2fa.ts b/packages/backend/test/e2e/2fa.ts index 289359a2ce..756a720652 100644 --- a/packages/backend/test/e2e/2fa.ts +++ b/packages/backend/test/e2e/2fa.ts @@ -53,7 +53,7 @@ describe('2要素認証', () => { const rpIdHash = (): Buffer => { return crypto.createHash('sha256') - .update(Buffer.from(config.host, 'utf-8')) + .update(Buffer.from(config.webHost, 'utf-8')) .digest(); }; @@ -103,7 +103,7 @@ describe('2要素認証', () => { clientDataJSON: Buffer.from(JSON.stringify({ type: 'webauthn.create', challenge: param.creationOptions.challenge, - origin: config.scheme + '://' + config.host, + origin: config.scheme + '://' + config.webHost, androidPackageName: 'org.mozilla.firefox', }), 'utf-8').toString('base64url'), attestationObject: cbor.encode({ @@ -149,7 +149,7 @@ describe('2要素認証', () => { const clientDataJSONBuffer = Buffer.from(JSON.stringify({ type: 'webauthn.get', challenge: param.requestOptions.challenge, - origin: config.scheme + '://' + config.host, + origin: config.scheme + '://' + config.webHost, androidPackageName: 'org.mozilla.firefox', }), 'utf-8'); const hashedclientDataJSON = crypto.createHash('sha256') @@ -191,7 +191,7 @@ describe('2要素認証', () => { assert.notEqual(registerResponse.body.url, undefined); assert.notEqual(registerResponse.body.secret, undefined); assert.strictEqual(registerResponse.body.label, username); - assert.strictEqual(registerResponse.body.issuer, config.host); + assert.strictEqual(registerResponse.body.issuer, config.webHost); const doneResponse = await api('i/2fa/done', { token: otpToken(registerResponse.body.secret), diff --git a/packages/backend/test/e2e/move.ts b/packages/backend/test/e2e/move.ts index fd798bdb25..b873570a9b 100644 --- a/packages/backend/test/e2e/move.ts +++ b/packages/backend/test/e2e/move.ts @@ -34,7 +34,7 @@ describe('Account Move', () => { jq = await jobQueue(); const config = loadConfig(); - url = new URL(config.url); + url = new URL(config.webUrl); const connection = await initTestDb(false); root = await signup({ username: 'root' }); alice = await signup({ username: 'alice' }); diff --git a/packages/backend/test/unit/activitypub.ts b/packages/backend/test/unit/activitypub.ts index ff93e1be07..8575159606 100644 --- a/packages/backend/test/unit/activitypub.ts +++ b/packages/backend/test/unit/activitypub.ts @@ -713,13 +713,13 @@ describe('ActivityPub', () => { it('should include id', async () => { const collection = await rendererService.renderRepliesCollection(note.id); - expect(collection.id).toBe(`${config.url}/notes/${note.id}/replies`); + expect(collection.id).toBe(`${config.webUrl}/notes/${note.id}/replies`); }); it('should include first', async () => { const collection = await rendererService.renderRepliesCollection(note.id); - expect(collection.first).toBe(`${config.url}/notes/${note.id}/replies?page=true`); + expect(collection.first).toBe(`${config.webUrl}/notes/${note.id}/replies?page=true`); }); it('should include totalItems', async () => { @@ -740,19 +740,19 @@ describe('ActivityPub', () => { it('should include id', async () => { const collection = await rendererService.renderRepliesCollectionPage(note.id, 'abc123'); - expect(collection.id).toBe(`${config.url}/notes/${note.id}/replies?page=true&until_id=abc123`); + expect(collection.id).toBe(`${config.webUrl}/notes/${note.id}/replies?page=true&until_id=abc123`); }); it('should include partOf', async () => { const collection = await rendererService.renderRepliesCollectionPage(note.id, 'abc123'); - expect(collection.partOf).toBe(`${config.url}/notes/${note.id}/replies`); + expect(collection.partOf).toBe(`${config.webUrl}/notes/${note.id}/replies`); }); it('should include first', async () => { const collection = await rendererService.renderRepliesCollectionPage(note.id, 'abc123'); - expect(collection.first).toBe(`${config.url}/notes/${note.id}/replies?page=true`); + expect(collection.first).toBe(`${config.webUrl}/notes/${note.id}/replies?page=true`); }); it('should include totalItems', async () => { @@ -778,19 +778,19 @@ describe('ActivityPub', () => { it('should include id', async () => { const collection = await rendererService.renderRepliesCollectionPage(note.id, undefined); - expect(collection.id).toBe(`${config.url}/notes/${note.id}/replies?page=true`); + expect(collection.id).toBe(`${config.webUrl}/notes/${note.id}/replies?page=true`); }); it('should include partOf', async () => { const collection = await rendererService.renderRepliesCollectionPage(note.id, undefined); - expect(collection.partOf).toBe(`${config.url}/notes/${note.id}/replies`); + expect(collection.partOf).toBe(`${config.webUrl}/notes/${note.id}/replies`); }); it('should include first', async () => { const collection = await rendererService.renderRepliesCollectionPage(note.id, undefined); - expect(collection.first).toBe(`${config.url}/notes/${note.id}/replies?page=true`); + expect(collection.first).toBe(`${config.webUrl}/notes/${note.id}/replies?page=true`); }); it('should include totalItems', async () => { diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts index 52cfb8ac93..742f9fe97c 100644 --- a/packages/backend/test/utils.ts +++ b/packages/backend/test/utils.ts @@ -40,8 +40,8 @@ export type SystemWebhookPayload = { const config = loadConfig(); export const port = config.port; -export const origin = config.url; -export const host = new URL(config.url).host; +export const origin = config.webUrl; +export const host = new URL(config.webUrl).host; export const WEBHOOK_HOST = 'http://localhost:15080'; export const WEBHOOK_PORT = 15080; diff --git a/packages/frontend-embed/src/boot.ts b/packages/frontend-embed/src/boot.ts index f11cfef8fd..e8476650a0 100644 --- a/packages/frontend-embed/src/boot.ts +++ b/packages/frontend-embed/src/boot.ts @@ -15,7 +15,7 @@ import { applyTheme, assertIsTheme } from '@/theme.js'; import { fetchCustomEmojis } from '@/custom-emojis.js'; import { DI } from '@/di.js'; import { serverMetadata } from '@/server-metadata.js'; -import { url, version, locale, lang, updateLocale, langsVersion } from '@@/js/config.js'; +import { webUrl, version, locale, lang, updateLocale, langsVersion } from '@@/js/config.js'; import { parseEmbedParams } from '@@/js/embed-page.js'; import { postMessageToParentWindow, setIframeId } from '@/post-message.js'; import { serverContext } from '@/server-context.js'; @@ -106,7 +106,7 @@ const app = createApp( defineAsyncComponent(() => import('@/ui.vue')), ); -app.provide(DI.mediaProxy, new MediaProxy(serverMetadata, url)); +app.provide(DI.mediaProxy, new MediaProxy(serverMetadata, webUrl)); app.provide(DI.serverMetadata, serverMetadata); diff --git a/packages/frontend-embed/src/components/EmAcct.vue b/packages/frontend-embed/src/components/EmAcct.vue index ff794d9b6e..2a8bd0ccc8 100644 --- a/packages/frontend-embed/src/components/EmAcct.vue +++ b/packages/frontend-embed/src/components/EmAcct.vue @@ -13,12 +13,12 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import * as Misskey from 'misskey-js'; import { toUnicode } from 'punycode.js'; -import { host as hostRaw } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; defineProps<{ user: Misskey.entities.UserLite; detail?: boolean; }>(); -const host = toUnicode(hostRaw); +const host = toUnicode(localHost); </script> diff --git a/packages/frontend-embed/src/components/EmLink.vue b/packages/frontend-embed/src/components/EmLink.vue index aec9b33072..945e73e5cd 100644 --- a/packages/frontend-embed/src/components/EmLink.vue +++ b/packages/frontend-embed/src/components/EmLink.vue @@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref } from 'vue'; import EmA from './EmA.vue'; -import { url as local } from '@@/js/config.js'; +import { webUrl as local } from '@@/js/config.js'; const props = withDefaults(defineProps<{ url: string; diff --git a/packages/frontend-embed/src/components/EmMention.vue b/packages/frontend-embed/src/components/EmMention.vue index b5aaa95894..5e76dc1e0f 100644 --- a/packages/frontend-embed/src/components/EmMention.vue +++ b/packages/frontend-embed/src/components/EmMention.vue @@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { toUnicode } from 'punycode.js'; import { } from 'vue'; import tinycolor from 'tinycolor2'; -import { host as localHost } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; const props = defineProps<{ username: string; diff --git a/packages/frontend-embed/src/components/EmMfm.ts b/packages/frontend-embed/src/components/EmMfm.ts index 74ae3373ef..fe51776b0b 100644 --- a/packages/frontend-embed/src/components/EmMfm.ts +++ b/packages/frontend-embed/src/components/EmMfm.ts @@ -7,7 +7,7 @@ import { h, provide } from 'vue'; import type { VNode, SetupContext } from 'vue'; import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; -import { host } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; import EmUrl from '@/components/EmUrl.vue'; import EmTime from '@/components/EmTime.vue'; import EmLink from '@/components/EmLink.vue'; @@ -379,7 +379,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven case 'mention': { return [h('bdi', h(EmMention, { key: Math.random(), - host: (token.props.host == null && props.author && props.author.host != null ? props.author.host : token.props.host) ?? host, + host: (token.props.host == null && props.author && props.author.host != null ? props.author.host : token.props.host) ?? localHost, username: token.props.username, }))]; } diff --git a/packages/frontend-embed/src/components/EmNote.vue b/packages/frontend-embed/src/components/EmNote.vue index 0dc77d09a7..253b5e30dc 100644 --- a/packages/frontend-embed/src/components/EmNote.vue +++ b/packages/frontend-embed/src/components/EmNote.vue @@ -65,7 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only /> </div> <div v-if="appearNote.files && appearNote.files.length > 0"> - <EmMediaList :mediaList="appearNote.files" :originalEntityUrl="`${url}/notes/${appearNote.id}`"/> + <EmMediaList :mediaList="appearNote.files" :originalEntityUrl="`${webUrl}/notes/${appearNote.id}`"/> </div> <EmPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :readOnly="true" :class="$style.poll"/> <div v-if="appearNote.renote" :class="$style.quote"><EmNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div> @@ -108,7 +108,7 @@ import { computed, inject, ref, shallowRef } from 'vue'; import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { shouldCollapsed } from '@@/js/collapsed.js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { computeMergedCw } from '@@/js/compute-merged-cw.js'; import I18n from '@/components/I18n.vue'; import EmNoteSub from '@/components/EmNoteSub.vue'; diff --git a/packages/frontend-embed/src/components/EmNoteDetailed.vue b/packages/frontend-embed/src/components/EmNoteDetailed.vue index 8a10778e8a..817503faf3 100644 --- a/packages/frontend-embed/src/components/EmNoteDetailed.vue +++ b/packages/frontend-embed/src/components/EmNoteDetailed.vue @@ -49,7 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.noteHeaderUsername"><EmAcct :user="appearNote.user"/></div> </div> <div :class="$style.noteHeaderInfo"> - <a :href="url" :class="$style.noteHeaderInstanceIconLink" target="_blank" rel="noopener noreferrer"> + <a :href="webUrl" :class="$style.noteHeaderInstanceIconLink" target="_blank" rel="noopener noreferrer"> <img :src="serverMetadata.iconUrl || '/favicon.ico'" alt="" :class="$style.noteHeaderInstanceIcon"/> </a> </div> @@ -76,7 +76,7 @@ SPDX-License-Identifier: AGPL-3.0-only /> </div> <div v-if="appearNote.files && appearNote.files.length > 0"> - <EmMediaList :mediaList="appearNote.files" :originalEntityUrl="`${url}/notes/${appearNote.id}`"/> + <EmMediaList :mediaList="appearNote.files" :originalEntityUrl="`${webUrl}/notes/${appearNote.id}`"/> </div> <EmPoll v-if="appearNote.poll" ref="pollViewer" :noteId="appearNote.id" :poll="appearNote.poll" :readOnly="true" :class="$style.poll"/> <div v-if="appearNote.renote" :class="$style.quote"><EmNoteSimple :note="appearNote.renote" :class="$style.quoteNote"/></div> @@ -148,7 +148,7 @@ import { notePage } from '@/utils.js'; import { i18n } from '@/i18n.js'; import { DI } from '@/di.js'; import { shouldCollapsed } from '@@/js/collapsed.js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import EmMfm from '@/components/EmMfm.js'; const props = defineProps<{ diff --git a/packages/frontend-embed/src/components/EmSubNoteContent.vue b/packages/frontend-embed/src/components/EmSubNoteContent.vue index e9acbcb293..4d9ac23da6 100644 --- a/packages/frontend-embed/src/components/EmSubNoteContent.vue +++ b/packages/frontend-embed/src/components/EmSubNoteContent.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> <details v-if="note.files && note.files.length > 0"> <summary>({{ i18n.tsx.withNFiles({ n: note.files.length }) }})</summary> - <EmMediaList :mediaList="note.files" :originalEntityUrl="`${url}/notes/${note.id}`"/> + <EmMediaList :mediaList="note.files" :originalEntityUrl="`${webUrl}/notes/${note.id}`"/> </details> <details v-if="note.poll"> <summary>{{ i18n.ts.poll }}</summary> @@ -35,7 +35,7 @@ import * as Misskey from 'misskey-js'; import EmMediaList from '@/components/EmMediaList.vue'; import EmPoll from '@/components/EmPoll.vue'; import { i18n } from '@/i18n.js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { shouldCollapsed } from '@@/js/collapsed.js'; import EmA from '@/components/EmA.vue'; import EmMfm from '@/components/EmMfm.js'; diff --git a/packages/frontend-embed/src/components/EmUrl.vue b/packages/frontend-embed/src/components/EmUrl.vue index 2dbbe90858..a3bd74270a 100644 --- a/packages/frontend-embed/src/components/EmUrl.vue +++ b/packages/frontend-embed/src/components/EmUrl.vue @@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { ref } from 'vue'; import { toUnicode as decodePunycode } from 'punycode.js'; import EmA from './EmA.vue'; -import { url as local } from '@@/js/config.js'; +import { webUrl as local } from '@@/js/config.js'; function safeURIDecode(str: string): string { try { diff --git a/packages/frontend-embed/src/pages/clip.vue b/packages/frontend-embed/src/pages/clip.vue index f4d4e8cf6f..0ee1cabfe8 100644 --- a/packages/frontend-embed/src/pages/clip.vue +++ b/packages/frontend-embed/src/pages/clip.vue @@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="_nowrap"><a :href="`/clips/${clip.id}`" target="_blank" rel="noopener">{{ clip.name }}</a></div> <div :class="$style.sub">{{ i18n.tsx.fromX({ x: instanceName }) }}</div> </div> - <a :href="url" :class="$style.instanceIconLink" target="_blank" rel="noopener noreferrer"> + <a :href="webUrl" :class="$style.instanceIconLink" target="_blank" rel="noopener noreferrer"> <img :class="$style.instanceIcon" :src="serverMetadata.iconUrl || '/favicon.ico'" @@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { ref, computed, inject, useTemplateRef } from 'vue'; import * as Misskey from 'misskey-js'; import { scrollToTop } from '@@/js/scroll.js'; -import { url, instanceName } from '@@/js/config.js'; +import { webUrl, instanceName } from '@@/js/config.js'; import { isLink } from '@@/js/is-link.js'; import { defaultEmbedParams } from '@@/js/embed-page.js'; import type { Paging } from '@/components/EmPagination.vue'; diff --git a/packages/frontend-embed/src/pages/tag.vue b/packages/frontend-embed/src/pages/tag.vue index 4b00ae7c2d..62d7953c70 100644 --- a/packages/frontend-embed/src/pages/tag.vue +++ b/packages/frontend-embed/src/pages/tag.vue @@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="_nowrap"><a :href="`/tags/${tag}`" target="_blank" rel="noopener">#{{ tag }}</a></div> <div :class="$style.sub">{{ i18n.tsx.fromX({ x: instanceName }) }}</div> </div> - <a :href="url" :class="$style.instanceIconLink" target="_blank" rel="noopener noreferrer"> + <a :href="webUrl" :class="$style.instanceIconLink" target="_blank" rel="noopener noreferrer"> <img :class="$style.instanceIcon" :src="serverMetadata.iconUrl || '/favicon.ico'" @@ -45,7 +45,7 @@ import EmNotes from '@/components/EmNotes.vue'; import XNotFound from '@/pages/not-found.vue'; import EmTimelineContainer from '@/components/EmTimelineContainer.vue'; import { i18n } from '@/i18n.js'; -import { url, instanceName } from '@@/js/config.js'; +import { webUrl, instanceName } from '@@/js/config.js'; import { isLink } from '@@/js/is-link.js'; import { DI } from '@/di.js'; import { defaultEmbedParams } from '@@/js/embed-page.js'; diff --git a/packages/frontend-embed/src/pages/user-timeline.vue b/packages/frontend-embed/src/pages/user-timeline.vue index 348b1a7622..6ae78af92d 100644 --- a/packages/frontend-embed/src/pages/user-timeline.vue +++ b/packages/frontend-embed/src/pages/user-timeline.vue @@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only </I18n> <div :class="$style.sub">{{ i18n.tsx.fromX({ x: instanceName }) }}</div> </div> - <a :href="url" :class="$style.instanceIconLink" target="_blank" rel="noopener noreferrer"> + <a :href="webUrl" :class="$style.instanceIconLink" target="_blank" rel="noopener noreferrer"> <img :class="$style.instanceIcon" :src="serverMetadata.iconUrl || '/favicon.ico'" @@ -47,7 +47,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script setup lang="ts"> import { ref, computed, inject, useTemplateRef } from 'vue'; import * as Misskey from 'misskey-js'; -import { url, instanceName } from '@@/js/config.js'; +import { webUrl, instanceName } from '@@/js/config.js'; import { defaultEmbedParams } from '@@/js/embed-page.js'; import type { Paging } from '@/components/EmPagination.vue'; import EmNotes from '@/components/EmNotes.vue'; diff --git a/packages/frontend-embed/src/utils.ts b/packages/frontend-embed/src/utils.ts index 939648aa38..c307b1588d 100644 --- a/packages/frontend-embed/src/utils.ts +++ b/packages/frontend-embed/src/utils.ts @@ -4,7 +4,7 @@ */ import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; export const acct = (user: Misskey.Acct) => { return Misskey.acct.toString(user); @@ -15,7 +15,7 @@ export const userName = (user: Misskey.entities.User) => { }; export const userPage = (user: Misskey.Acct, path?: string, absolute = false) => { - return `${absolute ? url : ''}/@${acct(user)}${(path ? `/${path}` : '')}`; + return `${absolute ? webUrl : ''}/@${acct(user)}${(path ? `/${path}` : '')}`; }; export const notePage = (note: Misskey.entities.Note) => { diff --git a/packages/frontend-shared/js/config.ts b/packages/frontend-shared/js/config.ts index 4c739e6e64..cd6fd9dbac 100644 --- a/packages/frontend-shared/js/config.ts +++ b/packages/frontend-shared/js/config.ts @@ -7,11 +7,15 @@ import type { Locale } from '../../../locales/index.js'; // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const address = new URL(document.querySelector<HTMLMetaElement>('meta[property="instance_url"]')?.content || location.href); +const localAddress = new URL(document.querySelector<HTMLMetaElement>('meta[property="local_url"]')?.content || location.href); const siteName = document.querySelector<HTMLMetaElement>('meta[property="og:site_name"]')?.content; -export const host = address.host; -export const hostname = address.hostname; -export const url = address.origin; +export const webHost = address.host; +export const webHostname = address.hostname; +export const webUrl = address.origin; +export const localHost = localAddress.host; +export const localHostname = localAddress.hostname; +export const localUrl = localAddress.origin; export const port = address.port; export const apiUrl = location.origin + '/api'; export const wsOrigin = location.origin; @@ -21,7 +25,7 @@ export const langsVersion = _LANGS_VERSION_; const preParseLocale = localStorage.getItem('locale'); export let locale: Locale = preParseLocale ? JSON.parse(preParseLocale) : null; export const version = _VERSION_; -export const instanceName = (siteName === 'Sharkey' || siteName == null) ? host : siteName; +export const instanceName = (siteName === 'Sharkey' || siteName == null) ? webHost : siteName; export const ui = localStorage.getItem('ui'); export const debug = localStorage.getItem('debug') === 'true'; diff --git a/packages/frontend/src/accounts.ts b/packages/frontend/src/accounts.ts index 4ee951bbd7..9ce21b9543 100644 --- a/packages/frontend/src/accounts.ts +++ b/packages/frontend/src/accounts.ts @@ -5,7 +5,7 @@ import { defineAsyncComponent, ref } from 'vue'; import * as Misskey from 'misskey-js'; -import { apiUrl, host } from '@@/js/config.js'; +import { apiUrl, localHost } from '@@/js/config.js'; import type { MenuItem } from '@/types/menu.js'; import { showSuspendedDialog } from '@/utility/show-suspended-dialog.js'; import { i18n } from '@/i18n.js'; @@ -137,7 +137,7 @@ export function updateCurrentAccount(accountData: Misskey.entities.MeDetailed) { for (const [key, value] of Object.entries(accountData)) { $i[key] = value; } - store.set('accountInfos', { ...store.s.accountInfos, [host + '/' + $i.id]: $i }); + store.set('accountInfos', { ...store.s.accountInfos, [localHost + '/' + $i.id]: $i }); $i.token = token; miLocalStorage.setItem('account', JSON.stringify($i)); } @@ -148,7 +148,7 @@ export function updateCurrentAccountPartial(accountData: Partial<Misskey.entitie $i[key] = value; } - store.set('accountInfos', { ...store.s.accountInfos, [host + '/' + $i.id]: $i }); + store.set('accountInfos', { ...store.s.accountInfos, [localHost + '/' + $i.id]: $i }); miLocalStorage.setItem('account', JSON.stringify($i)); } @@ -157,7 +157,7 @@ export async function refreshCurrentAccount() { if (!$i) return; return fetchAccount($i.token, $i.id).then(updateCurrentAccount).catch(reason => { if (reason === isAccountDeleted) { - removeAccount(host, $i.id); + removeAccount(localHost, $i.id); if (Object.keys(store.s.accountTokens).length > 0) { login(Object.values(store.s.accountTokens)[0]); } else { @@ -186,7 +186,7 @@ export async function login(token: AccountWithToken['token'], redirect?: string) token, })); - await addAccount(host, me, token); + await addAccount(localHost, me, token); if (redirect) { // 他のタブは再読み込みするだけ @@ -272,7 +272,7 @@ export async function openAccountMenu(opts: { }); if (opts.includeCurrentAccount) { - menuItems.push(createItem(host, $i.id, $i.username, $i, $i.token)); + menuItems.push(createItem(localHost, $i.id, $i.username, $i, $i.token)); } menuItems.push(...accountItems); @@ -295,7 +295,7 @@ export async function openAccountMenu(opts: { action: () => { getAccountWithSignupDialog().then(res => { if (res != null) { - switchAccount(host, res.id); + switchAccount(localHost, res.id); } }); }, @@ -313,7 +313,7 @@ export async function openAccountMenu(opts: { }); } else { if (opts.includeCurrentAccount) { - menuItems.push(createItem(host, $i.id, $i.username, $i, $i.token)); + menuItems.push(createItem(localHost, $i.id, $i.username, $i, $i.token)); } menuItems.push(...accountItems); @@ -329,7 +329,7 @@ export function getAccountWithSigninDialog(): Promise<{ id: string, token: strin const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSigninDialog.vue')), {}, { done: async (res: Misskey.entities.SigninFlowResponse & { finished: true }) => { const user = await fetchAccount(res.i, res.id, true); - await addAccount(host, user, res.i); + await addAccount(localHost, user, res.i); resolve({ id: res.id, token: res.i }); }, cancelled: () => { @@ -348,7 +348,7 @@ export function getAccountWithSignupDialog(): Promise<{ id: string, token: strin done: async (res: Misskey.entities.SignupResponse) => { const user = JSON.parse(JSON.stringify(res)); delete user.token; - await addAccount(host, user, res.token); + await addAccount(localHost, user, res.token); resolve({ id: res.id, token: res.token }); }, cancelled: () => { diff --git a/packages/frontend/src/aiscript/api.ts b/packages/frontend/src/aiscript/api.ts index 08ba89dd9d..444a770ba5 100644 --- a/packages/frontend/src/aiscript/api.ts +++ b/packages/frontend/src/aiscript/api.ts @@ -5,7 +5,7 @@ import { errors, utils, values } from '@syuilo/aiscript'; import * as Misskey from 'misskey-js'; -import { url, lang } from '@@/js/config.js'; +import { webUrl, lang } from '@@/js/config.js'; import { assertStringAndIsIn } from './common.js'; import * as os from '@/os.js'; import { misskeyApi } from '@/utility/misskey-api.js'; @@ -39,7 +39,7 @@ export function createAiScriptEnv(opts: { storageKey: string, token?: string }) USER_USERNAME: $i ? values.STR($i.username) : values.NULL, CUSTOM_EMOJIS: utils.jsToVal(customEmojis.value), LOCALE: values.STR(lang), - SERVER_URL: values.STR(url), + SERVER_URL: values.STR(webUrl), 'Mk:dialog': values.FN_NATIVE(async ([title, text, type]) => { utils.assertString(title); utils.assertString(text); diff --git a/packages/frontend/src/components/MkAccountMoved.vue b/packages/frontend/src/components/MkAccountMoved.vue index cb8032c019..e101c04793 100644 --- a/packages/frontend/src/components/MkAccountMoved.vue +++ b/packages/frontend/src/components/MkAccountMoved.vue @@ -16,7 +16,7 @@ import { ref } from 'vue'; import * as Misskey from 'misskey-js'; import MkMention from './MkMention.vue'; import { i18n } from '@/i18n.js'; -import { host as localHost } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; import { misskeyApi } from '@/utility/misskey-api.js'; const user = ref<Misskey.entities.UserLite>(); diff --git a/packages/frontend/src/components/MkDonation.vue b/packages/frontend/src/components/MkDonation.vue index dfdfc0a871..be0a737b60 100644 --- a/packages/frontend/src/components/MkDonation.vue +++ b/packages/frontend/src/components/MkDonation.vue @@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.text"> <I18n :src="i18n.ts.pleaseDonate" tag="span"> <template #host> - {{ instance.name ?? host }} + {{ instance.name ?? webHost }} </template> </I18n> <div style="margin-top: 0.2em;"> @@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div v-if="instance.donationUrl" :class="$style.text"> <I18n :src="i18n.ts.pleaseDonateInstance" tag="span"> <template #host> - {{ instance.name ?? host }} + {{ instance.name ?? webHost }} </template> </I18n> <div style="margin-top: 0.2em;"> @@ -48,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import MkButton from '@/components/MkButton.vue'; import MkLink from '@/components/MkLink.vue'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import { i18n } from '@/i18n.js'; import * as os from '@/os.js'; import { miLocalStorage } from '@/local-storage.js'; diff --git a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue index d18fe0ed0c..fdd129ef7d 100644 --- a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue +++ b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue @@ -90,7 +90,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script setup lang="ts"> import { useTemplateRef, ref, computed, nextTick, onMounted, onDeactivated, onUnmounted } from 'vue'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { embedRouteWithScrollbar } from '@@/js/embed-page.js'; import type { EmbeddableEntity, EmbedParams } from '@@/js/embed-page.js'; import MkModalWindow from '@/components/MkModalWindow.vue'; @@ -155,7 +155,7 @@ const embedPreviewUrl = computed(() => { const maxHeight = parseInt(paramClass.get('maxHeight')!); paramClass.set('maxHeight', maxHeight === 0 ? '500' : Math.min(maxHeight, 700).toString()); // プレビューであまりにも縮小されると見づらいため、700pxまでに制限 } - return `${url}/embed/${props.entity}/${props.id}${paramClass.toString() ? '?' + paramClass.toString() : ''}`; + return `${webUrl}/embed/${props.entity}/${props.id}${paramClass.toString() ? '?' + paramClass.toString() : ''}`; }); const isEmbedWithScrollbar = computed(() => embedRouteWithScrollbar.includes(props.entity)); diff --git a/packages/frontend/src/components/MkFollowButton.vue b/packages/frontend/src/components/MkFollowButton.vue index 1d86af39e5..cf655ab03e 100644 --- a/packages/frontend/src/components/MkFollowButton.vue +++ b/packages/frontend/src/components/MkFollowButton.vue @@ -37,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { onBeforeUnmount, onMounted, ref, watch } from 'vue'; import * as Misskey from 'misskey-js'; -import { host } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; import * as os from '@/os.js'; import { misskeyApi } from '@/utility/misskey-api.js'; import { useStream } from '@/stream.js'; @@ -86,7 +86,7 @@ function onFollowChange(user: Misskey.entities.UserDetailed) { } async function onClick() { - pleaseLogin({ openOnRemote: { type: 'web', path: `/@${props.user.username}@${props.user.host ?? host}` } }); + pleaseLogin({ openOnRemote: { type: 'web', path: `/@${props.user.username}@${props.user.host ?? localHost}` } }); wait.value = true; diff --git a/packages/frontend/src/components/MkLink.vue b/packages/frontend/src/components/MkLink.vue index 3a942b03dc..38ba05dfeb 100644 --- a/packages/frontend/src/components/MkLink.vue +++ b/packages/frontend/src/components/MkLink.vue @@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { defineAsyncComponent, ref } from 'vue'; -import { url as local } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { useTooltip } from '@/use/use-tooltip.js'; import * as os from '@/os.js'; import { isEnabledUrlPreview } from '@/instance.js'; @@ -33,7 +33,7 @@ const props = withDefaults(defineProps<{ }>(), { }); -const maybeRelativeUrl = maybeMakeRelative(props.url, local); +const maybeRelativeUrl = maybeMakeRelative(props.url, webUrl); const self = maybeRelativeUrl !== props.url; const attr = self ? 'to' : 'href'; const target = self ? null : '_blank'; diff --git a/packages/frontend/src/components/MkMention.vue b/packages/frontend/src/components/MkMention.vue index de8f39e7a8..0832c9e139 100644 --- a/packages/frontend/src/components/MkMention.vue +++ b/packages/frontend/src/components/MkMention.vue @@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { toUnicode } from 'punycode.js'; import { computed } from 'vue'; -import { host as localHost } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; import type { MkABehavior } from '@/components/global/MkA.vue'; import { $i } from '@/i.js'; import { getStaticImageUrl } from '@/utility/media-proxy.js'; diff --git a/packages/frontend/src/components/MkNote.vue b/packages/frontend/src/components/MkNote.vue index 56bfa5de94..9524cbaa4d 100644 --- a/packages/frontend/src/components/MkNote.vue +++ b/packages/frontend/src/components/MkNote.vue @@ -330,7 +330,7 @@ const allowAnim = ref(prefer.s.advancedMfm && prefer.s.animatedMfm); const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ type: 'lookup', - url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`, + url: appearNote.value.url ?? appearNote.value.uri ?? `${config.webUrl}/notes/${appearNote.value.id}`, })); const mergedCW = computed(() => computeMergedCw(appearNote.value)); diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 7f38b9ec02..4974799fdc 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -374,7 +374,7 @@ let renoting = false; const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ type: 'lookup', - url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`, + url: appearNote.value.url ?? appearNote.value.uri ?? `${config.webUrl}/notes/${appearNote.value.id}`, })); const keymap = { diff --git a/packages/frontend/src/components/MkNoteSub.vue b/packages/frontend/src/components/MkNoteSub.vue index 58de5bd5a7..36fd6d3ec0 100644 --- a/packages/frontend/src/components/MkNoteSub.vue +++ b/packages/frontend/src/components/MkNoteSub.vue @@ -154,7 +154,7 @@ const mergedCW = computed(() => computeMergedCw(appearNote.value)); const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ type: 'lookup', - url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`, + url: appearNote.value.url ?? appearNote.value.uri ?? `${config.webUrl}/notes/${appearNote.value.id}`, })); const currentClip = inject<Ref<Misskey.entities.Clip> | null>('currentClip', null); diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue index 44112775dc..7d475b5a96 100644 --- a/packages/frontend/src/components/MkPageWindow.vue +++ b/packages/frontend/src/components/MkPageWindow.vue @@ -31,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, onMounted, onUnmounted, provide, ref, useTemplateRef } from 'vue'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import type { PageMetadata } from '@/page.js'; import MkUserName from './global/MkUserName.vue'; import RouterView from '@/components/global/RouterView.vue'; @@ -135,14 +135,14 @@ const contextmenu = computed(() => ([{ icon: 'ti ti-external-link', text: i18n.ts.openInNewTab, action: () => { - window.open(url + windowRouter.getCurrentFullPath(), '_blank', 'noopener'); + window.open(webUrl + windowRouter.getCurrentFullPath(), '_blank', 'noopener'); windowEl.value?.close(); }, }, { icon: 'ti ti-link', text: i18n.ts.copyLink, action: () => { - copyToClipboard(url + windowRouter.getCurrentFullPath()); + copyToClipboard(webUrl + windowRouter.getCurrentFullPath()); }, }])); diff --git a/packages/frontend/src/components/MkPoll.vue b/packages/frontend/src/components/MkPoll.vue index 72f3ced088..ecafb66c52 100644 --- a/packages/frontend/src/components/MkPoll.vue +++ b/packages/frontend/src/components/MkPoll.vue @@ -72,7 +72,7 @@ const showResult = ref(props.readOnly || isVoted.value); const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ type: 'lookup', - url: `${config.url}/notes/${props.noteId}`, + url: `${config.webUrl}/notes/${props.noteId}`, })); // 期限付きアンケート diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue index a650365a28..ca4855a084 100644 --- a/packages/frontend/src/components/MkPostForm.vue +++ b/packages/frontend/src/components/MkPostForm.vue @@ -111,7 +111,7 @@ import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import insertTextAtCursor from 'insert-text-at-cursor'; import { toASCII } from 'punycode.js'; -import { host, url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { appendContentWarning } from '@@/js/append-content-warning.js'; import type { ShallowRef } from 'vue'; import type { MenuItem } from '@/types/menu.js'; @@ -715,7 +715,7 @@ async function onPaste(ev: ClipboardEvent) { const paste = ev.clipboardData.getData('text'); - if (!renoteTargetNote.value && !quoteId.value && paste.startsWith(url + '/notes/') && !$i.rejectQuotes) { + if (!renoteTargetNote.value && !quoteId.value && paste.startsWith(webUrl + '/notes/') && !$i.rejectQuotes) { ev.preventDefault(); os.confirm({ @@ -727,7 +727,7 @@ async function onPaste(ev: ClipboardEvent) { return; } - quoteId.value = paste.substring(url.length).match(/^\/notes\/(.+?)\/?$/)?.[1] ?? null; + quoteId.value = paste.substring(webUrl.length).match(/^\/notes\/(.+?)\/?$/)?.[1] ?? null; }); } @@ -1023,7 +1023,7 @@ async function post(ev?: MouseEvent) { 'https://open.spotify.com/track/7anfcaNPQWlWCwyCHmZqNy', 'https://open.spotify.com/track/5Odr16TvEN4my22K9nbH7l', 'https://open.spotify.com/album/5bOlxyl4igOrp2DwVQxBco', - ].some(url => text.includes(url))) { + ].some(webUrl => text.includes(webUrl))) { claimAchievement('brainDiver'); } diff --git a/packages/frontend/src/components/MkPreview.vue b/packages/frontend/src/components/MkPreview.vue index d8dfbd1655..a400bd9825 100644 --- a/packages/frontend/src/components/MkPreview.vue +++ b/packages/frontend/src/components/MkPreview.vue @@ -48,7 +48,7 @@ import { $i } from '@/i.js'; const text = ref(''); const flag = ref(true); const radio = ref('misskey'); -const mfm = ref(`Hello world! This is an @example mention. BTW you are @${$i ? $i.username : 'guest'}.\nAlso, here is ${config.url} and [example link](${config.url}). for more details, see https://example.com.\nAs you know #misskey is open-source software.`); +const mfm = ref(`Hello world! This is an @example mention. BTW you are @${$i ? $i.username : 'guest'}.\nAlso, here is ${config.webUrl} and [example link](${config.webUrl}). for more details, see https://example.com.\nAs you know #misskey is open-source software.`); const openDialog = async () => { await os.alert({ diff --git a/packages/frontend/src/components/MkSignin.input.vue b/packages/frontend/src/components/MkSignin.input.vue index aacd1eae2a..b6563d93f8 100644 --- a/packages/frontend/src/components/MkSignin.input.vue +++ b/packages/frontend/src/components/MkSignin.input.vue @@ -57,7 +57,7 @@ import { ref } from 'vue'; import { toUnicode } from 'punycode.js'; import { query, extractDomain } from '@@/js/url.js'; -import { host as configHost } from '@@/js/config.js'; +import { localHost as configHost } from '@@/js/config.js'; import type { OpenOnRemoteOptions } from '@/utility/please-login.js'; import { i18n } from '@/i18n.js'; import * as os from '@/os.js'; diff --git a/packages/frontend/src/components/MkSignupDialog.form.vue b/packages/frontend/src/components/MkSignupDialog.form.vue index 003c68309d..3f327b86d8 100644 --- a/packages/frontend/src/components/MkSignupDialog.form.vue +++ b/packages/frontend/src/components/MkSignupDialog.form.vue @@ -110,7 +110,7 @@ const emit = defineEmits<{ (ev: 'approvalPending'): void; }>(); -const host = toUnicode(config.host); +const host = toUnicode(config.webHost); const hcaptcha = ref<Captcha | undefined>(); const mcaptcha = ref<Captcha | undefined>(); diff --git a/packages/frontend/src/components/MkSourceCodeAvailablePopup.vue b/packages/frontend/src/components/MkSourceCodeAvailablePopup.vue index 84dc244b23..a8421f1f64 100644 --- a/packages/frontend/src/components/MkSourceCodeAvailablePopup.vue +++ b/packages/frontend/src/components/MkSourceCodeAvailablePopup.vue @@ -15,14 +15,14 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.title"> <I18n :src="i18n.ts.aboutX" tag="span"> <template #x> - {{ instance.name ?? host }} + {{ instance.name ?? webHost }} </template> </I18n> </div> <div :class="$style.text"> <I18n :src="i18n.ts._aboutMisskey.thisIsModifiedVersion" tag="span"> <template #name> - {{ instance.name ?? host }} + {{ instance.name ?? webHost }} </template> </I18n> <I18n :src="i18n.ts.correspondingSourceIsAvailable" tag="span"> @@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import MkButton from '@/components/MkButton.vue'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import { i18n } from '@/i18n.js'; import { instance } from '@/instance.js'; import { miLocalStorage } from '@/local-storage.js'; diff --git a/packages/frontend/src/components/MkTutorialDialog.vue b/packages/frontend/src/components/MkTutorialDialog.vue index d6abbf6504..99aa04091c 100644 --- a/packages/frontend/src/components/MkTutorialDialog.vue +++ b/packages/frontend/src/components/MkTutorialDialog.vue @@ -133,7 +133,7 @@ SPDX-License-Identifier: AGPL-3.0-only <a href="https://misskey-hub.net/docs/for-users/" target="_blank" class="_link">{{ i18n.ts.help }}</a> </template> </I18n> - <div>{{ i18n.tsx._initialAccountSetting.haveFun({ name: instance.name ?? host }) }}</div> + <div>{{ i18n.tsx._initialAccountSetting.haveFun({ name: instance.name ?? webHost }) }}</div> <div class="_buttonsCenter" style="margin-top: 16px;"> <MkButton v-if="initialPage !== 4" rounded @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton> <MkButton rounded primary gradate @click="close(false)">{{ i18n.ts.close }}</MkButton> @@ -149,7 +149,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, useTemplateRef, watch } from 'vue'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import MkModalWindow from '@/components/MkModalWindow.vue'; import MkButton from '@/components/MkButton.vue'; import XNote from '@/components/MkTutorialDialog.Note.vue'; diff --git a/packages/frontend/src/components/MkUrlPreview.vue b/packages/frontend/src/components/MkUrlPreview.vue index 5d0e6e3df7..d300a96ce3 100644 --- a/packages/frontend/src/components/MkUrlPreview.vue +++ b/packages/frontend/src/components/MkUrlPreview.vue @@ -113,7 +113,7 @@ export type SummalyResult = Awaited<ReturnType<typeof summaly>> & { <script lang="ts" setup> import { defineAsyncComponent, onDeactivated, onUnmounted, ref } from 'vue'; -import { url as local } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { versatileLang } from '@@/js/intl-const.js'; import * as Misskey from 'misskey-js'; import { maybeMakeRelative } from '@@/js/url.js'; @@ -155,7 +155,7 @@ const MOBILE_THRESHOLD = 500; const isMobile = ref(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD); const hidePreview = ref<boolean>(false); -const maybeRelativeUrl = maybeMakeRelative(props.url, local); +const maybeRelativeUrl = maybeMakeRelative(props.url, webUrl); const self = maybeRelativeUrl !== props.url; const attr = self ? 'to' : 'href'; const target = self ? null : '_blank'; diff --git a/packages/frontend/src/components/MkUserSelectDialog.vue b/packages/frontend/src/components/MkUserSelectDialog.vue index 34ed1f8fc2..d2322eb90a 100644 --- a/packages/frontend/src/components/MkUserSelectDialog.vue +++ b/packages/frontend/src/components/MkUserSelectDialog.vue @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template #label>{{ i18n.ts.username }}</template> <template #prefix>@</template> </MkInput> - <MkInput v-model="host" :datalist="[hostname]" debounce @update:modelValue="search"> + <MkInput v-model="host" :datalist="[localHostname]" debounce @update:modelValue="search"> <template #label>{{ i18n.ts.host }}</template> <template #prefix>@</template> </MkInput> @@ -63,7 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { onMounted, ref, computed, useTemplateRef } from 'vue'; import * as Misskey from 'misskey-js'; -import { host as currentHost, hostname } from '@@/js/config.js'; +import { localHostname } from '@@/js/config.js'; import MkInput from '@/components/MkInput.vue'; import FormSplit from '@/components/form/split.vue'; import MkModalWindow from '@/components/MkModalWindow.vue'; diff --git a/packages/frontend/src/components/MkUserSetupDialog.vue b/packages/frontend/src/components/MkUserSetupDialog.vue index 82214ed5a5..f5e04de567 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.vue +++ b/packages/frontend/src/components/MkUserSetupDialog.vue @@ -93,7 +93,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="_gaps" style="text-align: center;"> <i class="ti ti-bell-ringing-2" style="display: block; margin: auto; font-size: 3em; color: var(--MI_THEME-accent);"></i> <div style="font-size: 120%;">{{ i18n.ts.pushNotification }}</div> - <div style="padding: 0 16px;">{{ i18n.tsx._initialAccountSetting.pushNotificationDescription({ name: instance.name ?? host }) }}</div> + <div style="padding: 0 16px;">{{ i18n.tsx._initialAccountSetting.pushNotificationDescription({ name: instance.name ?? webHost }) }}</div> <MkPushNotificationAllowButton primary showOnlyToRegister style="margin: 0 auto;"/> <div class="_buttonsCenter" style="margin-top: 16px;"> <MkButton rounded data-cy-user-setup-back @click="page--"><i class="ti ti-arrow-left"></i> {{ i18n.ts.goBack }}</MkButton> @@ -110,7 +110,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div class="_gaps" style="text-align: center;"> <i class="ti ti-check" style="display: block; margin: auto; font-size: 3em; color: var(--MI_THEME-accent);"></i> <div style="font-size: 120%;">{{ i18n.ts._initialAccountSetting.initialAccountSettingCompleted }}</div> - <div>{{ i18n.tsx._initialAccountSetting.youCanContinueTutorial({ name: instance.name ?? host }) }}</div> + <div>{{ i18n.tsx._initialAccountSetting.youCanContinueTutorial({ name: instance.name ?? webHost }) }}</div> <div class="_buttonsCenter" style="margin-top: 16px;"> <MkButton rounded primary gradate data-cy-user-setup-continue @click="launchTutorial()">{{ i18n.ts._initialAccountSetting.startTutorial }} <i class="ti ti-arrow-right"></i></MkButton> </div> @@ -129,7 +129,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, useTemplateRef, watch, nextTick, defineAsyncComponent } from 'vue'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import MkModalWindow from '@/components/MkModalWindow.vue'; import MkButton from '@/components/MkButton.vue'; import XProfile from '@/components/MkUserSetupDialog.Profile.vue'; diff --git a/packages/frontend/src/components/SkNote.vue b/packages/frontend/src/components/SkNote.vue index 4d6d080ddf..b6e311aad9 100644 --- a/packages/frontend/src/components/SkNote.vue +++ b/packages/frontend/src/components/SkNote.vue @@ -329,7 +329,7 @@ const allowAnim = ref(prefer.s.advancedMfm && prefer.s.animatedMfm); const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ type: 'lookup', - url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`, + url: appearNote.value.url ?? appearNote.value.uri ?? `${config.webUrl}/notes/${appearNote.value.id}`, })); const mergedCW = computed(() => computeMergedCw(appearNote.value)); diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index f761029cfb..a023160432 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -379,7 +379,7 @@ let renoting = false; const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ type: 'lookup', - url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`, + url: appearNote.value.url ?? appearNote.value.uri ?? `${config.webUrl}/notes/${appearNote.value.id}`, })); const keymap = { diff --git a/packages/frontend/src/components/SkNoteSub.vue b/packages/frontend/src/components/SkNoteSub.vue index 4e8a3147ad..82b604cc60 100644 --- a/packages/frontend/src/components/SkNoteSub.vue +++ b/packages/frontend/src/components/SkNoteSub.vue @@ -168,7 +168,7 @@ const mergedCW = computed(() => computeMergedCw(appearNote.value)); const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({ type: 'lookup', - url: appearNote.value.url ?? appearNote.value.uri ?? `${config.url}/notes/${appearNote.value.id}`, + url: appearNote.value.url ?? appearNote.value.uri ?? `${config.webUrl}/notes/${appearNote.value.id}`, })); const currentClip = inject<Ref<Misskey.entities.Clip> | null>('currentClip', null); diff --git a/packages/frontend/src/components/global/MkA.vue b/packages/frontend/src/components/global/MkA.vue index 9a51acc9dc..c972c87cce 100644 --- a/packages/frontend/src/components/global/MkA.vue +++ b/packages/frontend/src/components/global/MkA.vue @@ -15,7 +15,7 @@ export type MkABehavior = 'window' | 'browser' | null; <script lang="ts" setup> import { computed, inject, useTemplateRef } from 'vue'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import * as os from '@/os.js'; import { copyToClipboard } from '@/utility/copy-to-clipboard.js'; import { i18n } from '@/i18n.js'; @@ -76,7 +76,7 @@ function onContextmenu(ev) { icon: 'ti ti-link', text: i18n.ts.copyLink, action: () => { - copyToClipboard(`${url}${props.to}`); + copyToClipboard(`${webUrl}${props.to}`); }, }], ev); } diff --git a/packages/frontend/src/components/global/MkAcct.vue b/packages/frontend/src/components/global/MkAcct.vue index ff794d9b6e..ea6ec10442 100644 --- a/packages/frontend/src/components/global/MkAcct.vue +++ b/packages/frontend/src/components/global/MkAcct.vue @@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import * as Misskey from 'misskey-js'; import { toUnicode } from 'punycode.js'; -import { host as hostRaw } from '@@/js/config.js'; +import { localHost as hostRaw } from '@@/js/config.js'; defineProps<{ user: Misskey.entities.UserLite; diff --git a/packages/frontend/src/components/global/MkAd.vue b/packages/frontend/src/components/global/MkAd.vue index 525c47da45..eecccd40bc 100644 --- a/packages/frontend/src/components/global/MkAd.vue +++ b/packages/frontend/src/components/global/MkAd.vue @@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only </component> </div> <div v-else :class="$style.menu"> - <div>Ads by {{ host }}</div> + <div>Ads by {{ webHost }}</div> <!--<MkButton class="button" primary>{{ i18n.ts._ad.like }}</MkButton>--> <MkButton v-if="chosen.ratio !== 0" :class="$style.menuButton" @click="reduceFrequency">{{ i18n.ts._ad.reduceFrequencyOfThisAd }}</MkButton> <button class="_textButton" @click="toggleMenu">{{ i18n.ts._ad.back }}</button> @@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, computed } from 'vue'; -import { url as local, host } from '@@/js/config.js'; +import { webUrl as local, webHost } from '@@/js/config.js'; import { i18n } from '@/i18n.js'; import { instance } from '@/instance.js'; import MkButton from '@/components/MkButton.vue'; diff --git a/packages/frontend/src/components/global/MkMfm.ts b/packages/frontend/src/components/global/MkMfm.ts index 9f92c43b68..72ff1722e4 100644 --- a/packages/frontend/src/components/global/MkMfm.ts +++ b/packages/frontend/src/components/global/MkMfm.ts @@ -6,7 +6,7 @@ import { h, defineAsyncComponent } from 'vue'; import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; -import { host } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; import CkFollowMouse from '../CkFollowMouse.vue'; import type { VNode, SetupContext } from 'vue'; import type { MkABehavior } from '@/components/global/MkA.vue'; @@ -432,7 +432,7 @@ export default function MkMfm(props: MfmProps, { emit }: { emit: SetupContext<Mf case 'mention': { return [h('bdi', h(MkMention, { key: Math.random(), - host: (token.props.host == null && props.author && props.author.host != null ? props.author.host : token.props.host) ?? host, + host: (token.props.host == null && props.author && props.author.host != null ? props.author.host : token.props.host) ?? localHost, username: token.props.username, navigationBehavior: props.linkNavigationBehavior, }))]; diff --git a/packages/frontend/src/components/global/MkUrl.vue b/packages/frontend/src/components/global/MkUrl.vue index 058f03aeac..2f84e305ee 100644 --- a/packages/frontend/src/components/global/MkUrl.vue +++ b/packages/frontend/src/components/global/MkUrl.vue @@ -29,7 +29,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { defineAsyncComponent, ref } from 'vue'; import { toUnicode as decodePunycode } from 'punycode.js'; -import { url as local } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import * as os from '@/os.js'; import { useTooltip } from '@/use/use-tooltip.js'; import { isEnabledUrlPreview } from '@/instance.js'; @@ -54,7 +54,7 @@ const props = withDefaults(defineProps<{ showUrlPreview: true, }); -const maybeRelativeUrl = maybeMakeRelative(props.url, local); +const maybeRelativeUrl = maybeMakeRelative(props.url, webUrl); const self = maybeRelativeUrl !== props.url; const url = new URL(props.url); if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url'); diff --git a/packages/frontend/src/filters/user.ts b/packages/frontend/src/filters/user.ts index d9bc316764..a69a27deb6 100644 --- a/packages/frontend/src/filters/user.ts +++ b/packages/frontend/src/filters/user.ts @@ -4,7 +4,7 @@ */ import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; export const acct = (user: Misskey.Acct) => { return Misskey.acct.toString(user); @@ -15,5 +15,5 @@ export const userName = (user: Misskey.entities.User) => { }; export const userPage = (user: Misskey.Acct, path?: string, absolute = false) => { - return `${absolute ? url : ''}/@${acct(user)}${(path ? `/${path}` : '')}`; + return `${absolute ? webUrl : ''}/@${acct(user)}${(path ? `/${path}` : '')}`; }; diff --git a/packages/frontend/src/pages/about.overview.vue b/packages/frontend/src/pages/about.overview.vue index 241ee3c388..e587e8f93d 100644 --- a/packages/frontend/src/pages/about.overview.vue +++ b/packages/frontend/src/pages/about.overview.vue @@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div style="overflow: clip;"> <img :src="instance.sidebarLogoUrl ?? instance.iconUrl ?? '/favicon.ico'" alt="" :class="$style.bannerIcon"/> <div :class="$style.bannerName"> - <b>{{ instance.name ?? host }}</b> + <b>{{ instance.name ?? webHost }}</b> </div> </div> </div> @@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template #key>Sharkey</template> <template #value>{{ version }}</template> </MkKeyValue> - <div v-html="i18n.tsx.poweredByMisskeyDescription({ name: instance.name ?? host })"> + <div v-html="i18n.tsx.poweredByMisskeyDescription({ name: instance.name ?? webHost })"> </div> <FormLink to="/about-sharkey"> <template #icon><i class="ti ti-info-circle"></i></template> @@ -148,7 +148,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref } from 'vue'; -import { host, version } from '@@/js/config.js'; +import { webHost, version } from '@@/js/config.js'; import { i18n } from '@/i18n.js'; import { instance } from '@/instance.js'; import number from '@/filters/number.js'; diff --git a/packages/frontend/src/pages/admin-user.vue b/packages/frontend/src/pages/admin-user.vue index dc29ae2f80..9ca6fbef34 100644 --- a/packages/frontend/src/pages/admin-user.vue +++ b/packages/frontend/src/pages/admin-user.vue @@ -279,7 +279,6 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, defineAsyncComponent, watch, ref } from 'vue'; import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; import type { Badge } from '@/components/SkBadgeStrip.vue'; import type { ChartSrc } from '@/components/MkChart.vue'; import MkChart from '@/components/MkChart.vue'; diff --git a/packages/frontend/src/pages/admin/branding.vue b/packages/frontend/src/pages/admin/branding.vue index 64faf49848..5427350e1a 100644 --- a/packages/frontend/src/pages/admin/branding.vue +++ b/packages/frontend/src/pages/admin/branding.vue @@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template #prefix><i class="ti ti-link"></i></template> <template #label>{{ i18n.ts._serverSettings.iconUrl }} (App/192px)</template> <template #caption> - <div>{{ i18n.tsx._serverSettings.appIconDescription({ host: instance.name ?? host }) }}</div> + <div>{{ i18n.tsx._serverSettings.appIconDescription({ host: instance.name ?? webHost }) }}</div> <div>({{ i18n.ts._serverSettings.appIconUsageExample }})</div> <div>{{ i18n.ts._serverSettings.appIconStyleRecommendation }}</div> <div><strong>{{ i18n.tsx._serverSettings.appIconResolutionMustBe({ resolution: '192x192px' }) }}</strong></div> @@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template #prefix><i class="ti ti-link"></i></template> <template #label>{{ i18n.ts._serverSettings.iconUrl }} (App/512px)</template> <template #caption> - <div>{{ i18n.tsx._serverSettings.appIconDescription({ host: instance.name ?? host }) }}</div> + <div>{{ i18n.tsx._serverSettings.appIconDescription({ host: instance.name ?? webHost }) }}</div> <div>({{ i18n.ts._serverSettings.appIconUsageExample }})</div> <div>{{ i18n.ts._serverSettings.appIconStyleRecommendation }}</div> <div><strong>{{ i18n.tsx._serverSettings.appIconResolutionMustBe({ resolution: '512x512px' }) }}</strong></div> @@ -119,7 +119,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, computed } from 'vue'; import JSON5 from 'json5'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import MkInput from '@/components/MkInput.vue'; import MkTextarea from '@/components/MkTextarea.vue'; import FromSlot from '@/components/form/slot.vue'; diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue index 56d037758f..f56c127eb1 100644 --- a/packages/frontend/src/pages/channel.vue +++ b/packages/frontend/src/pages/channel.vue @@ -74,7 +74,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, watch, ref } from 'vue'; import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import type { PageHeaderItem } from '@/types/page-header.js'; import MkPostForm from '@/components/MkPostForm.vue'; import MkTimeline from '@/components/MkTimeline.vue'; @@ -238,7 +238,7 @@ const headerActions = computed(() => { console.warn('failed to copy channel URL. channel.value is null.'); return; } - copyToClipboard(`${url}/channels/${channel.value.id}`); + copyToClipboard(`${webUrl}/channels/${channel.value.id}`); }, }); @@ -255,7 +255,7 @@ const headerActions = computed(() => { navigator.share({ title: channel.value.name, text: channel.value.description ?? undefined, - url: `${url}/channels/${channel.value.id}`, + url: `${webUrl}/channels/${channel.value.id}`, }); }, }); diff --git a/packages/frontend/src/pages/chat/XMessage.vue b/packages/frontend/src/pages/chat/XMessage.vue index b72583214b..6e643b5110 100644 --- a/packages/frontend/src/pages/chat/XMessage.vue +++ b/packages/frontend/src/pages/chat/XMessage.vue @@ -55,7 +55,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { computed, defineAsyncComponent, provide } from 'vue'; import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { isLink } from '@@/js/is-link.js'; import type { MenuItem } from '@/types/menu.js'; import type { NormalizedChatMessage } from './room.vue'; @@ -183,7 +183,7 @@ function showMenu(ev: MouseEvent, contextmenu = false) { text: i18n.ts.reportAbuse, icon: 'ti ti-exclamation-circle', action: () => { - const localUrl = `${url}/chat/messages/${props.message.id}`; + const localUrl = `${webUrl}/chat/messages/${props.message.id}`; const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), { user: props.message.fromUser!, initialComment: `${localUrl}\n-----\n`, diff --git a/packages/frontend/src/pages/clip.vue b/packages/frontend/src/pages/clip.vue index 87a361c1e2..0417fe5289 100644 --- a/packages/frontend/src/pages/clip.vue +++ b/packages/frontend/src/pages/clip.vue @@ -32,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, watch, provide, ref } from 'vue'; import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import type { MenuItem } from '@/types/menu.js'; import MkNotes from '@/components/MkNotes.vue'; import { $i } from '@/i.js'; @@ -146,7 +146,7 @@ const headerActions = computed(() => clip.value && isOwned.value ? [{ icon: 'ti ti-link', text: i18n.ts.copyUrl, action: () => { - copyToClipboard(`${url}/clips/${clip.value!.id}`); + copyToClipboard(`${webUrl}/clips/${clip.value!.id}`); }, }, { icon: 'ti ti-code', @@ -164,7 +164,7 @@ const headerActions = computed(() => clip.value && isOwned.value ? [{ navigator.share({ title: clip.value!.name, text: clip.value!.description ?? '', - url: `${url}/clips/${clip.value!.id}`, + url: `${webUrl}/clips/${clip.value!.id}`, }); }, }); diff --git a/packages/frontend/src/pages/explore.featured.vue b/packages/frontend/src/pages/explore.featured.vue index 82badd40b3..189e1848d0 100644 --- a/packages/frontend/src/pages/explore.featured.vue +++ b/packages/frontend/src/pages/explore.featured.vue @@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div v-else-if="tab === 'polls'"> <template v-if="ltlAvailable || gtlAvailable"> <MkFoldableSection v-if="ltlAvailable" class="_margin"> - <template #header><i class="ph-house ph-bold ph-lg" style="margin-right: 0.5em;"></i>{{ i18n.tsx.pollsOnLocal({ name: instance.name ?? host }) }}</template> + <template #header><i class="ph-house ph-bold ph-lg" style="margin-right: 0.5em;"></i>{{ i18n.tsx.pollsOnLocal({ name: instance.name ?? webHost }) }}</template> <MkNotes :pagination="paginationForPollsLocal" :disableAutoLoad="true"/> </MkFoldableSection> @@ -37,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, ref } from 'vue'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import MkNotes from '@/components/MkNotes.vue'; import MkTab from '@/components/MkTab.vue'; import { i18n } from '@/i18n.js'; diff --git a/packages/frontend/src/pages/explore.users.vue b/packages/frontend/src/pages/explore.users.vue index 77fe21c33f..94701865aa 100644 --- a/packages/frontend/src/pages/explore.users.vue +++ b/packages/frontend/src/pages/explore.users.vue @@ -46,7 +46,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template v-if="tag == null"> <MkFoldableSection class="_margin"> - <template #header><i class="ti ti-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.tsx.popularUsersLocal({ name: instance.name ?? host }) }}</template> + <template #header><i class="ti ti-chart-line ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.tsx.popularUsersLocal({ name: instance.name ?? webHost }) }}</template> <MkUserList :pagination="popularUsersLocalF"/> </MkFoldableSection> <MkFoldableSection class="_margin"> @@ -69,7 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { watch, ref, useTemplateRef, computed } from 'vue'; import * as Misskey from 'misskey-js'; -import { host } from '@@/js/config'; +import { webHost } from '@@/js/config'; import MkUserList from '@/components/MkUserList.vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; import MkTab from '@/components/MkTab.vue'; diff --git a/packages/frontend/src/pages/flash/flash.vue b/packages/frontend/src/pages/flash/flash.vue index b17faca2a9..90152a9571 100644 --- a/packages/frontend/src/pages/flash/flash.vue +++ b/packages/frontend/src/pages/flash/flash.vue @@ -64,7 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { computed, onDeactivated, onUnmounted, ref, watch, shallowRef, defineAsyncComponent } from 'vue'; import * as Misskey from 'misskey-js'; import { Interpreter, Parser, values } from '@syuilo/aiscript'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import type { Ref } from 'vue'; import type { AsUiComponent, AsUiRoot } from '@/aiscript/ui.js'; import type { MenuItem } from '@/types/menu.js'; @@ -127,7 +127,7 @@ function share(ev: MouseEvent) { function copyLink() { if (!flash.value) return; - copyToClipboard(`${url}/play/${flash.value.id}`); + copyToClipboard(`${webUrl}/play/${flash.value.id}`); } function shareWithNavigator() { @@ -136,7 +136,7 @@ function shareWithNavigator() { navigator.share({ title: flash.value.title, text: flash.value.summary, - url: `${url}/play/${flash.value.id}`, + url: `${webUrl}/play/${flash.value.id}`, }); } @@ -144,7 +144,7 @@ function shareWithNote() { if (!flash.value) return; os.post({ - initialText: `${flash.value.title}\n${url}/play/${flash.value.id}`, + initialText: `${flash.value.title}\n${webUrl}/play/${flash.value.id}`, instant: true, }); } @@ -206,7 +206,7 @@ async function run() { root.value = _root.value; }), THIS_ID: values.STR(flash.value.id), - THIS_URL: values.STR(`${url}/play/${flash.value.id}`), + THIS_URL: values.STR(`${webUrl}/play/${flash.value.id}`), }, { in: aiScriptReadline, out: (value) => { @@ -241,7 +241,7 @@ async function run() { function reportAbuse() { if (!flash.value) return; - const pageUrl = `${url}/play/${flash.value.id}`; + const pageUrl = `${webUrl}/play/${flash.value.id}`; const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), { user: flash.value.user, diff --git a/packages/frontend/src/pages/gallery/post.vue b/packages/frontend/src/pages/gallery/post.vue index 7c754f0b03..16cfd250a1 100644 --- a/packages/frontend/src/pages/gallery/post.vue +++ b/packages/frontend/src/pages/gallery/post.vue @@ -64,7 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, watch, ref, defineAsyncComponent } from 'vue'; import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import type { MenuItem } from '@/types/menu.js'; import MkButton from '@/components/MkButton.vue'; import * as os from '@/os.js'; @@ -109,20 +109,20 @@ function fetchPost() { } function copyLink() { - copyToClipboard(`${url}/gallery/${post.value.id}`); + copyToClipboard(`${webUrl}/gallery/${post.value.id}`); } function share() { navigator.share({ title: post.value.title, text: post.value.description, - url: `${url}/gallery/${post.value.id}`, + url: `${webUrl}/gallery/${post.value.id}`, }); } function shareWithNote() { os.post({ - initialText: `${post.value.title} ${url}/gallery/${post.value.id}`, + initialText: `${post.value.title} ${webUrl}/gallery/${post.value.id}`, }); } @@ -156,7 +156,7 @@ function edit() { function reportAbuse() { if (!post.value) return; - const pageUrl = `${url}/gallery/${post.value.id}`; + const pageUrl = `${webUrl}/gallery/${post.value.id}`; const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), { user: post.value.user, diff --git a/packages/frontend/src/pages/note.vue b/packages/frontend/src/pages/note.vue index 85befbb18b..a3119a4de8 100644 --- a/packages/frontend/src/pages/note.vue +++ b/packages/frontend/src/pages/note.vue @@ -151,7 +151,7 @@ function fetchNote() { message: i18n.ts.thisContentsAreMarkedAsSigninRequiredByAuthor, openOnRemote: { type: 'lookup', - url: `${config.url}/notes/${props.noteId}`, + url: `${config.webUrl}/notes/${props.noteId}`, }, }); } diff --git a/packages/frontend/src/pages/page-editor/page-editor.vue b/packages/frontend/src/pages/page-editor/page-editor.vue index 7368e0329a..f67fd591cf 100644 --- a/packages/frontend/src/pages/page-editor/page-editor.vue +++ b/packages/frontend/src/pages/page-editor/page-editor.vue @@ -63,7 +63,6 @@ SPDX-License-Identifier: AGPL-3.0-only import { computed, provide, watch, ref } from 'vue'; import * as Misskey from 'misskey-js'; import { v4 as uuid } from 'uuid'; -import { url } from '@@/js/config.js'; import XBlocks from './page-editor.blocks.vue'; import MkButton from '@/components/MkButton.vue'; import MkSelect from '@/components/MkSelect.vue'; diff --git a/packages/frontend/src/pages/page.vue b/packages/frontend/src/pages/page.vue index f4d0f25734..50a828aef9 100644 --- a/packages/frontend/src/pages/page.vue +++ b/packages/frontend/src/pages/page.vue @@ -99,7 +99,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, watch, ref, defineAsyncComponent } from 'vue'; import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import type { MenuItem } from '@/types/menu.js'; import XPage from '@/components/page/page.vue'; import MkButton from '@/components/MkButton.vue'; @@ -188,14 +188,14 @@ function share(ev: MouseEvent) { function copyLink() { if (!page.value) return; - copyToClipboard(`${url}/@${page.value.user.username}/pages/${page.value.name}`); + copyToClipboard(`${webUrl}/@${page.value.user.username}/pages/${page.value.name}`); } function shareWithNote() { if (!page.value) return; os.post({ - initialText: `${page.value.title || page.value.name}\n${url}/@${page.value.user.username}/pages/${page.value.name}`, + initialText: `${page.value.title || page.value.name}\n${webUrl}/@${page.value.user.username}/pages/${page.value.name}`, instant: true, }); } @@ -206,7 +206,7 @@ function shareWithNavigator() { navigator.share({ title: page.value.title ?? page.value.name, text: page.value.summary ?? undefined, - url: `${url}/@${page.value.user.username}/pages/${page.value.name}`, + url: `${webUrl}/@${page.value.user.username}/pages/${page.value.name}`, }); } @@ -248,7 +248,7 @@ function pin(pin) { function reportAbuse() { if (!page.value) return; - const pageUrl = `${url}/@${props.username}/pages/${props.pageName}`; + const pageUrl = `${webUrl}/@${props.username}/pages/${props.pageName}`; const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), { user: page.value.user, diff --git a/packages/frontend/src/pages/reversi/game.board.vue b/packages/frontend/src/pages/reversi/game.board.vue index 1c1adaf687..d5ffecf2b4 100644 --- a/packages/frontend/src/pages/reversi/game.board.vue +++ b/packages/frontend/src/pages/reversi/game.board.vue @@ -146,7 +146,7 @@ import { computed, onActivated, onDeactivated, onMounted, onUnmounted, ref, shal import * as Misskey from 'misskey-js'; import * as Reversi from 'misskey-reversi'; import { useInterval } from '@@/js/use-interval.js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import MkButton from '@/components/MkButton.vue'; import MkFolder from '@/components/MkFolder.vue'; import MkSwitch from '@/components/MkSwitch.vue'; @@ -443,7 +443,7 @@ function autoplay() { function share() { os.post({ - initialText: `#MisskeyReversi\n${url}/reversi/g/${game.value.id}`, + initialText: `#MisskeyReversi\n${webUrl}/reversi/g/${game.value.id}`, instant: true, }); } diff --git a/packages/frontend/src/pages/reversi/game.vue b/packages/frontend/src/pages/reversi/game.vue index a447572cc0..fa40fee70d 100644 --- a/packages/frontend/src/pages/reversi/game.vue +++ b/packages/frontend/src/pages/reversi/game.vue @@ -20,7 +20,7 @@ import { useStream } from '@/stream.js'; import { ensureSignin } from '@/i.js'; import { useRouter } from '@/router.js'; import * as os from '@/os.js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { i18n } from '@/i18n.js'; import { useInterval } from '@@/js/use-interval.js'; @@ -45,7 +45,7 @@ function start(_game: Misskey.entities.ReversiGameDetailed) { if (shareWhenStart.value) { misskeyApi('notes/create', { - text: `${i18n.ts._reversi.iStartedAGame}\n${url}/reversi/g/${props.gameId}`, + text: `${i18n.ts._reversi.iStartedAGame}\n${webUrl}/reversi/g/${props.gameId}`, visibility: 'home', }); } diff --git a/packages/frontend/src/pages/search.note.vue b/packages/frontend/src/pages/search.note.vue index 85183637f4..2fd72df6d5 100644 --- a/packages/frontend/src/pages/search.note.vue +++ b/packages/frontend/src/pages/search.note.vue @@ -127,7 +127,7 @@ import { computed, ref, shallowRef, toRef } from 'vue'; import type * as Misskey from 'misskey-js'; import type { Paging } from '@/components/MkPagination.vue'; import { $i } from '@/i.js'; -import { host as localHost } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import { i18n } from '@/i18n.js'; import { instance } from '@/instance.js'; import * as os from '@/os.js'; @@ -207,7 +207,7 @@ type SearchParams = { }; const fixHostIfLocal = (target: string | null | undefined) => { - if (!target || target === localHost) return '.'; + if (!target || target === webHost) return '.'; return target; }; diff --git a/packages/frontend/src/pages/settings/2fa.qrdialog.vue b/packages/frontend/src/pages/settings/2fa.qrdialog.vue index 5bb125e67c..2b147a1d5f 100644 --- a/packages/frontend/src/pages/settings/2fa.qrdialog.vue +++ b/packages/frontend/src/pages/settings/2fa.qrdialog.vue @@ -106,7 +106,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { hostname, port } from '@@/js/config'; +import { localHostname, port } from '@@/js/config'; import { useTemplateRef, ref } from 'vue'; import MkButton from '@/components/MkButton.vue'; import MkModalWindow from '@/components/MkModalWindow.vue'; @@ -162,7 +162,7 @@ function downloadBackupCodes() { const txtBlob = new Blob([backupCodes.value.join('\n')], { type: 'text/plain' }); const dummya = window.document.createElement('a'); dummya.href = URL.createObjectURL(txtBlob); - dummya.download = `${$i.username}@${hostname}` + (port !== '' ? `_${port}` : '') + '-2fa-backup-codes.txt'; + dummya.download = `${$i.username}@${localHostname}` + (port !== '' ? `_${port}` : '') + '-2fa-backup-codes.txt'; dummya.click(); } } diff --git a/packages/frontend/src/pages/settings/profile.attribution-domains-setting.vue b/packages/frontend/src/pages/settings/profile.attribution-domains-setting.vue index c77870f9d3..7a0f2ceb41 100644 --- a/packages/frontend/src/pages/settings/profile.attribution-domains-setting.vue +++ b/packages/frontend/src/pages/settings/profile.attribution-domains-setting.vue @@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, watch, computed } from 'vue'; -import { host as hostRaw } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; import { toUnicode } from 'punycode.js'; import MkTextarea from '@/components/MkTextarea.vue'; import MkButton from '@/components/MkButton.vue'; @@ -36,7 +36,7 @@ const domainArray = computed(() => { .filter(el => el); }); const changed = ref(false); -const tutorialTag = '`<meta name="fediverse:creator" content="' + $i.username + '@' + toUnicode(hostRaw) + '" />`'; +const tutorialTag = '`<meta name="fediverse:creator" content="' + $i.username + '@' + toUnicode(localHost) + '" />`'; async function save() { // checks for a full line without whitespace. diff --git a/packages/frontend/src/pages/theme-editor.vue b/packages/frontend/src/pages/theme-editor.vue index 585d96bd08..4facc6edce 100644 --- a/packages/frontend/src/pages/theme-editor.vue +++ b/packages/frontend/src/pages/theme-editor.vue @@ -79,7 +79,7 @@ import { v4 as uuid } from 'uuid'; import JSON5 from 'json5'; import lightTheme from '@@/themes/_light.json5'; import darkTheme from '@@/themes/_dark.json5'; -import { host } from '@@/js/config.js'; +import { localHost } from '@@/js/config.js'; import type { Theme } from '@/theme.js'; import MkButton from '@/components/MkButton.vue'; import MkCodeEditor from '@/components/MkCodeEditor.vue'; @@ -190,7 +190,7 @@ async function saveAs() { theme.value.id = uuid(); theme.value.name = name; - theme.value.author = `@${$i.username}@${toUnicode(host)}`; + theme.value.author = `@${$i.username}@${toUnicode(localHost)}`; if (description.value) theme.value.desc = description.value; await addTheme(theme.value); applyTheme(theme.value); diff --git a/packages/frontend/src/pages/welcome.setup.vue b/packages/frontend/src/pages/welcome.setup.vue index 4d9c0bb742..f84f11dcab 100644 --- a/packages/frontend/src/pages/welcome.setup.vue +++ b/packages/frontend/src/pages/welcome.setup.vue @@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only <MkInput v-model="username" pattern="^[a-zA-Z0-9_]{1,20}$" :spellcheck="false" required data-cy-admin-username> <template #label>{{ i18n.ts.username }}</template> <template #prefix>@</template> - <template #suffix>@{{ host }}</template> + <template #suffix>@{{ localHost }}</template> </MkInput> <MkInput v-model="password" type="password" data-cy-admin-password> <template #label>{{ i18n.ts.password }}</template> @@ -40,7 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref } from 'vue'; -import { host, version } from '@@/js/config.js'; +import { localHost, version } from '@@/js/config.js'; import MkButton from '@/components/MkButton.vue'; import MkInput from '@/components/MkInput.vue'; import * as os from '@/os.js'; diff --git a/packages/frontend/src/preferences/manager.ts b/packages/frontend/src/preferences/manager.ts index 349040d98e..9e882ea9ed 100644 --- a/packages/frontend/src/preferences/manager.ts +++ b/packages/frontend/src/preferences/manager.ts @@ -5,7 +5,7 @@ import { computed, nextTick, onUnmounted, ref, watch } from 'vue'; import { v4 as uuid } from 'uuid'; -import { host, version } from '@@/js/config.js'; +import { localHost, version } from '@@/js/config.js'; import { PREF_DEF } from './def.js'; import type { Ref, WritableComputedRef } from 'vue'; import type { MenuItem } from '@/types/menu.js'; @@ -182,7 +182,7 @@ export class PreferencesManager { if (parseScope(record[0]).account == null && this.isAccountDependentKey(key)) { this.profile.preferences[key].push([makeScope({ - server: host, + server: localHost, account: $i!.id, }), v, {}]); this.save(); @@ -191,7 +191,7 @@ export class PreferencesManager { if (parseScope(record[0]).server == null && this.isServerDependentKey(key)) { this.profile.preferences[key].push([makeScope({ - server: host, + server: localHost, }), v, {}]); this.save(); return; @@ -339,10 +339,10 @@ export class PreferencesManager { if ($i == null) return records.find(([scope, v]) => parseScope(scope).account == null)!; - const accountOverrideRecord = records.find(([scope, v]) => parseScope(scope).server === host && parseScope(scope).account === $i!.id); + const accountOverrideRecord = records.find(([scope, v]) => parseScope(scope).server === localHost && parseScope(scope).account === $i!.id); if (accountOverrideRecord) return accountOverrideRecord; - const serverOverrideRecord = records.find(([scope, v]) => parseScope(scope).server === host && parseScope(scope).account == null); + const serverOverrideRecord = records.find(([scope, v]) => parseScope(scope).server === localHost && parseScope(scope).account == null); if (serverOverrideRecord) return serverOverrideRecord; const record = records.find(([scope, v]) => parseScope(scope).account == null); @@ -351,7 +351,7 @@ export class PreferencesManager { public isAccountOverrided<K extends keyof PREF>(key: K): boolean { if ($i == null) return false; - return this.profile.preferences[key].some(([scope, v]) => parseScope(scope).server === host && parseScope(scope).account === $i!.id) ?? false; + return this.profile.preferences[key].some(([scope, v]) => parseScope(scope).server === localHost && parseScope(scope).account === $i!.id) ?? false; } public setAccountOverride<K extends keyof PREF>(key: K) { @@ -361,7 +361,7 @@ export class PreferencesManager { const records = this.profile.preferences[key]; records.push([makeScope({ - server: host, + server: localHost, account: $i!.id, }), this.s[key], {}]); @@ -374,7 +374,7 @@ export class PreferencesManager { const records = this.profile.preferences[key]; - const index = records.findIndex(([scope, v]) => parseScope(scope).server === host && parseScope(scope).account === $i!.id); + const index = records.findIndex(([scope, v]) => parseScope(scope).server === localHost && parseScope(scope).account === $i!.id); if (index === -1) return; records.splice(index, 1); diff --git a/packages/frontend/src/ui/_common_/common.ts b/packages/frontend/src/ui/_common_/common.ts index fcb9f2acfc..11b7eb6c6d 100644 --- a/packages/frontend/src/ui/_common_/common.ts +++ b/packages/frontend/src/ui/_common_/common.ts @@ -7,7 +7,7 @@ import { defineAsyncComponent } from 'vue'; import type { MenuItem } from '@/types/menu.js'; import * as os from '@/os.js'; import { instance } from '@/instance.js'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import { i18n } from '@/i18n.js'; import { $i } from '@/i.js'; @@ -44,7 +44,7 @@ export function openInstanceMenu(ev: MouseEvent) { const menuItems: MenuItem[] = []; menuItems.push({ - text: instance.name ?? host, + text: instance.name ?? webHost, type: 'label', }, { type: 'link', diff --git a/packages/frontend/src/ui/_common_/titlebar.vue b/packages/frontend/src/ui/_common_/titlebar.vue index 4450e60b18..d0c1e4c623 100644 --- a/packages/frontend/src/ui/_common_/titlebar.vue +++ b/packages/frontend/src/ui/_common_/titlebar.vue @@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.root"> <div :class="$style.title"> <img :src="instance.sidebarLogoUrl || instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="instance.sidebarLogoUrl ? $style.wideInstanceIcon : $style.instanceIcon"/> - <span :class="$style.instanceTitle">{{ instance.name ?? host }}</span> + <span :class="$style.instanceTitle">{{ instance.name ?? webHost }}</span> </div> <div :class="$style.controls"> <span :class="$style.left"> @@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import { ref } from 'vue'; import { instance } from '@/instance.js'; import { prefer } from '@/preferences.js'; diff --git a/packages/frontend/src/utility/get-embed-code.ts b/packages/frontend/src/utility/get-embed-code.ts index d458e64f19..c4741d73f5 100644 --- a/packages/frontend/src/utility/get-embed-code.ts +++ b/packages/frontend/src/utility/get-embed-code.ts @@ -4,7 +4,7 @@ */ import { defineAsyncComponent } from 'vue'; import { v4 as uuid } from 'uuid'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { defaultEmbedParams, embedRouteWithScrollbar } from '@@/js/embed-page.js'; import type { EmbedParams, EmbeddableEntity } from '@@/js/embed-page.js'; import * as os from '@/os.js'; @@ -53,8 +53,8 @@ export function getEmbedCode(path: string, params?: EmbedParams): string { } const iframeCode = [ - `<iframe src="${url + path + paramString}" data-misskey-embed-id="${iframeId}" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; max-width: 500px; height: 300px; color-scheme: light dark;"></iframe>`, - `<script defer src="${url}/embed.js"></script>`, + `<iframe src="${webUrl + path + paramString}" data-misskey-embed-id="${iframeId}" loading="lazy" referrerpolicy="strict-origin-when-cross-origin" style="border: none; width: 100%; max-width: 500px; height: 300px; color-scheme: light dark;"></iframe>`, + `<script defer src="${webUrl}/embed.js"></script>`, ]; return iframeCode.join('\n'); } diff --git a/packages/frontend/src/utility/get-note-menu.ts b/packages/frontend/src/utility/get-note-menu.ts index 056480a7ef..0096ed68da 100644 --- a/packages/frontend/src/utility/get-note-menu.ts +++ b/packages/frontend/src/utility/get-note-menu.ts @@ -5,7 +5,7 @@ import { defineAsyncComponent } from 'vue'; import * as Misskey from 'misskey-js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { claimAchievement } from './achievements.js'; import type { Ref, ShallowRef } from 'vue'; import type { MenuItem } from '@/types/menu.js'; @@ -137,7 +137,7 @@ export function getAbuseNoteMenu(note: Misskey.entities.Note, text: string): Men icon: 'ti ti-exclamation-circle', text, action: (): void => { - const localUrl = `${url}/notes/${note.id}`; + const localUrl = `${webUrl}/notes/${note.id}`; let noteInfo = ''; if (note.url ?? note.uri != null) noteInfo = `Note: ${note.url ?? note.uri}\n`; noteInfo += `Local Note: ${localUrl}\n`; @@ -156,7 +156,7 @@ export function getCopyNoteLinkMenu(note: Misskey.entities.Note, text: string): icon: 'ti ti-link', text, action: (): void => { - copyToClipboard(`${url}/notes/${note.id}`); + copyToClipboard(`${webUrl}/notes/${note.id}`); }, }; } @@ -282,7 +282,7 @@ export function getNoteMenu(props: { navigator.share({ title: i18n.tsx.noteOf({ user: appearNote.user.name ?? appearNote.user.username }), text: appearNote.text ?? '', - url: `${url}/notes/${appearNote.id}`, + url: `${webUrl}/notes/${appearNote.id}`, }); } diff --git a/packages/frontend/src/utility/get-user-menu.ts b/packages/frontend/src/utility/get-user-menu.ts index fde390cece..e1a746b579 100644 --- a/packages/frontend/src/utility/get-user-menu.ts +++ b/packages/frontend/src/utility/get-user-menu.ts @@ -6,7 +6,7 @@ import { toUnicode } from 'punycode.js'; import { defineAsyncComponent, ref, watch } from 'vue'; import * as Misskey from 'misskey-js'; -import { host, url } from '@@/js/config.js'; +import { localHost, webUrl } from '@@/js/config.js'; import type { Router } from '@/router.js'; import type { MenuItem } from '@/types/menu.js'; import { i18n } from '@/i18n.js'; @@ -164,7 +164,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router icon: 'ti ti-at', text: i18n.ts.copyUsername, action: () => { - copyToClipboard(`@${user.username}@${user.host ?? host}`); + copyToClipboard(`@${user.username}@${user.host ?? localHost}`); }, }); @@ -173,7 +173,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router text: i18n.ts.copyProfileUrl, action: () => { const canonical = user.host === null ? `@${user.username}` : `@${user.username}@${toUnicode(user.host)}`; - copyToClipboard(`${url}/${canonical}`); + copyToClipboard(`${webUrl}/${canonical}`); }, }); @@ -181,7 +181,7 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: Router icon: 'ti ti-rss', text: i18n.ts.copyRSS, action: () => { - copyToClipboard(`${user.host ?? host}/@${user.username}.atom`); + copyToClipboard(`${user.host ?? localHost}/@${user.username}.atom`); }, }); diff --git a/packages/frontend/src/utility/getNoteUrls.ts b/packages/frontend/src/utility/getNoteUrls.ts index efd014cbf0..c92e3a868b 100644 --- a/packages/frontend/src/utility/getNoteUrls.ts +++ b/packages/frontend/src/utility/getNoteUrls.ts @@ -9,7 +9,7 @@ import type * as Misskey from 'misskey-js'; export function getNoteUrls(note: Misskey.entities.Note): string[] { const urls: string[] = [ // Any note - `${config.url}/notes/${note.id}`, + `${config.webUrl}/notes/${note.id}`, ]; // Remote note @@ -18,7 +18,7 @@ export function getNoteUrls(note: Misskey.entities.Note): string[] { if (note.reply) { // Any Reply - urls.push(`${config.url}/notes/${note.reply.id}`); + urls.push(`${config.webUrl}/notes/${note.reply.id}`); // Remote Reply if (note.reply.url) urls.push(note.reply.url); if (note.reply.uri) urls.push(note.reply.uri); @@ -26,7 +26,7 @@ export function getNoteUrls(note: Misskey.entities.Note): string[] { if (note.renote) { // Any Renote - urls.push(`${config.url}/notes/${note.renote.id}`); + urls.push(`${config.webUrl}/notes/${note.renote.id}`); // Remote Renote if (note.renote.url) urls.push(note.renote.url); if (note.renote.uri) urls.push(note.renote.uri); @@ -34,7 +34,7 @@ export function getNoteUrls(note: Misskey.entities.Note): string[] { if (note.renote?.renote) { // Any Quote - urls.push(`${config.url}/notes/${note.renote.renote.id}`); + urls.push(`${config.webUrl}/notes/${note.renote.renote.id}`); // Remote Quote if (note.renote.renote.url) urls.push(note.renote.renote.url); if (note.renote.renote.uri) urls.push(note.renote.renote.uri); diff --git a/packages/frontend/src/utility/media-proxy.ts b/packages/frontend/src/utility/media-proxy.ts index 78eba35ead..d93c0448d1 100644 --- a/packages/frontend/src/utility/media-proxy.ts +++ b/packages/frontend/src/utility/media-proxy.ts @@ -4,14 +4,14 @@ */ import { MediaProxy } from '@@/js/media-proxy.js'; -import { url } from '@@/js/config.js'; +import { webUrl } from '@@/js/config.js'; import { instance } from '@/instance.js'; let _mediaProxy: MediaProxy | null = null; export function getProxiedImageUrl(...args: Parameters<MediaProxy['getProxiedImageUrl']>): string { if (_mediaProxy == null) { - _mediaProxy = new MediaProxy(instance, url); + _mediaProxy = new MediaProxy(instance, webUrl); } return _mediaProxy.getProxiedImageUrl(...args); @@ -19,7 +19,7 @@ export function getProxiedImageUrl(...args: Parameters<MediaProxy['getProxiedIma export function getProxiedImageUrlNullable(...args: Parameters<MediaProxy['getProxiedImageUrlNullable']>): string | null { if (_mediaProxy == null) { - _mediaProxy = new MediaProxy(instance, url); + _mediaProxy = new MediaProxy(instance, webUrl); } return _mediaProxy.getProxiedImageUrlNullable(...args); @@ -27,7 +27,7 @@ export function getProxiedImageUrlNullable(...args: Parameters<MediaProxy['getPr export function getStaticImageUrl(...args: Parameters<MediaProxy['getStaticImageUrl']>): string { if (_mediaProxy == null) { - _mediaProxy = new MediaProxy(instance, url); + _mediaProxy = new MediaProxy(instance, webUrl); } return _mediaProxy.getStaticImageUrl(...args); diff --git a/packages/frontend/src/utility/player-url-transform.ts b/packages/frontend/src/utility/player-url-transform.ts index 39c6df6500..068a11874e 100644 --- a/packages/frontend/src/utility/player-url-transform.ts +++ b/packages/frontend/src/utility/player-url-transform.ts @@ -2,7 +2,7 @@ * SPDX-FileCopyrightText: syuilo and misskey-project * SPDX-License-Identifier: AGPL-3.0-only */ -import { hostname } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; export function transformPlayerUrl(url: string): string { const urlObj = new URL(url); @@ -13,7 +13,7 @@ export function transformPlayerUrl(url: string): string { if (urlObj.hostname === 'player.twitch.tv') { // TwitchはCSPの制約あり // https://dev.twitch.tv/docs/embed/video-and-clips/ - urlParams.set('parent', hostname); + urlParams.set('parent', webHost); urlParams.set('allowfullscreen', ''); urlParams.set('autoplay', 'true'); } else { diff --git a/packages/frontend/src/utility/popout.ts b/packages/frontend/src/utility/popout.ts index 5b141222e8..6cde3d8a33 100644 --- a/packages/frontend/src/utility/popout.ts +++ b/packages/frontend/src/utility/popout.ts @@ -7,7 +7,7 @@ import { appendQuery } from '@@/js/url.js'; import * as config from '@@/js/config.js'; export function popout(path: string, w?: HTMLElement) { - let url = path.startsWith('http://') || path.startsWith('https://') ? path : config.url + path; + let url = path.startsWith('http://') || path.startsWith('https://') ? path : config.webUrl + path; url = appendQuery(url, 'zen'); if (w) { const position = w.getBoundingClientRect(); diff --git a/packages/frontend/src/widgets/WidgetInstanceInfo.vue b/packages/frontend/src/widgets/WidgetInstanceInfo.vue index 9708b63a8d..4ace9c25b4 100644 --- a/packages/frontend/src/widgets/WidgetInstanceInfo.vue +++ b/packages/frontend/src/widgets/WidgetInstanceInfo.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.bodyContainer"> <div :class="$style.body"> <MkA :class="$style.name" to="/about" behavior="window">{{ instance.name }}</MkA> - <div :class="$style.host">{{ host }}</div> + <div :class="$style.host">{{ webHost }}</div> </div> </div> </div> @@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; import type { GetFormResultType } from '@/utility/form.js'; -import { host } from '@@/js/config.js'; +import { webHost } from '@@/js/config.js'; import { instance } from '@/instance.js'; const name = 'instanceInfo'; diff --git a/packages/frontend/src/widgets/WidgetRss.vue b/packages/frontend/src/widgets/WidgetRss.vue index 132eb0a629..8583d56c89 100644 --- a/packages/frontend/src/widgets/WidgetRss.vue +++ b/packages/frontend/src/widgets/WidgetRss.vue @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, watch, computed } from 'vue'; import * as Misskey from 'misskey-js'; -import { url as base } from '@@/js/config.js'; +import { webUrl as base } from '@@/js/config.js'; import { useInterval } from '@@/js/use-interval.js'; import { useWidgetPropsManager } from './widget.js'; import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js'; diff --git a/packages/frontend/src/widgets/WidgetRssTicker.vue b/packages/frontend/src/widgets/WidgetRssTicker.vue index b5be4d35c2..86346626b0 100644 --- a/packages/frontend/src/widgets/WidgetRssTicker.vue +++ b/packages/frontend/src/widgets/WidgetRssTicker.vue @@ -35,7 +35,7 @@ import MarqueeText from '@/components/MkMarquee.vue'; import type { GetFormResultType } from '@/utility/form.js'; import MkContainer from '@/components/MkContainer.vue'; import { shuffle } from '@/utility/shuffle.js'; -import { url as base } from '@@/js/config.js'; +import { webUrl as base } from '@@/js/config.js'; import { useInterval } from '@@/js/use-interval.js'; const name = 'rssTicker'; |