Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .config/cypress-devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ setupPassword: example_password_please_change_this_or_you_will_get_hacked
# Final accessible URL seen by a user.
url: 'http://misskey.local'

# Use a seperate hostname for federation. All users on this
# instance will appear with this host instead of the one with
# the misskey web url if set.
#localHost: 'misskey.local'

# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# URL SETTINGS AFTER THAT!

Expand Down
5 changes: 5 additions & 0 deletions .config/docker_example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
# You can set url from an environment variable instead.
url: https://example.tld/

# Use a seperate hostname for federation. All users on this
# instance will appear with this host instead of the one with
# the misskey web url if set.
#localHost: 'example.tld'

# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# URL SETTINGS AFTER THAT!

Expand Down
5 changes: 5 additions & 0 deletions .config/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
# Final accessible URL seen by a user.
url: https://example.tld/

# Use a seperate hostname for federation. All users on this
# instance will appear with this host instead of the one with
# the misskey web url if set.
#localHost: 'example.tld'

# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# URL SETTINGS AFTER THAT!

Expand Down
5 changes: 5 additions & 0 deletions .devcontainer/devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
# Final accessible URL seen by a user.
url: http://127.0.0.1:3000/

# Use a seperate hostname for federation. All users on this
# instance will appear with this host instead of the one with
# the misskey web url if set.
#localHost: '127.0.0.1:3000'

# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
# URL SETTINGS AFTER THAT!

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@

### General
- 依存関係の更新
- Added `localHost` option to allow misskey instances to federate their users on a different host than the one from the accessable web url.

### Client
- Enhance: アプリ内ウィンドウの初期サイズを画面サイズに応じて自動で調整するように
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type RedisOptionsSource = Partial<RedisOptions> & {
*/
type Source = {
url?: string;
localHost?: string;
port?: number;
socket?: string;
trustProxy?: FastifyServerOptions['trustProxy'];
Expand Down Expand Up @@ -119,6 +120,7 @@ type Source = {

export type Config = {
url: string;
localHost: string;
port: number;
socket: string | undefined;
trustProxy: NonNullable<FastifyServerOptions['trustProxy']>;
Expand Down Expand Up @@ -259,6 +261,7 @@ export function loadConfig(): Config {
const hostname = url.hostname;
const scheme = url.protocol.replace(/:$/, '');
const wsScheme = scheme.replace('http', 'ws');
const localHost = config.localHost ?? host;

const dbDb = config.db.db ?? process.env.DATABASE_DB ?? '';
const dbUser = config.db.user ?? process.env.DATABASE_USER ?? '';
Expand All @@ -275,6 +278,7 @@ export function loadConfig(): Config {
publishTarballInsteadOfProvideRepositoryUrl: !!config.publishTarballInsteadOfProvideRepositoryUrl,
setupPassword: config.setupPassword,
url: url.origin,
localHost,
port: config.port ?? parseInt(process.env.PORT ?? '', 10),
socket: config.socket,
trustProxy: config.trustProxy ?? [
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/core/MfmService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ export class MfmService {
const remoteUserInfo = mentionedRemoteUsers.find(remoteUser => remoteUser.username.toLowerCase() === username.toLowerCase() && remoteUser.host?.toLowerCase() === host?.toLowerCase());
const 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.url}/${acct.endsWith(`@${this.config.localHost}`) ? acct.substring(0, acct.length - this.config.localHost.length - 1) : acct}`;
try {
const url = new URL(href);
return `<a href="${escapeHtml(url.href)}" class="u-url mention">${escapeHtml(acct)}</a>`;
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/core/RemoteUserResolveService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,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)) || (host === this.utilityService.toPuny(this.config.host))) {
this.logger.info(`return local user: ${usernameLower}`);
return await this.usersRepository.findOneBy({ usernameLower, host: IsNull() }).then(u => {
if (u == null) {
Expand Down
5 changes: 3 additions & 2 deletions packages/backend/src/core/UtilityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ 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.host) === this.toPuny(host));
}

@bindThis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ export class ApPersonService implements OnModuleInit {
if (typeof uri !== 'string') throw new Error('uri 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.host))) {
throw new StatusError('cannot resolve local user', 400, 'cannot resolve local user');
}

Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/core/entities/UserEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,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.host || 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.url}/identicon/${user.username.toLowerCase()}@${user.host ?? this.config.localHost}`;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/server/ServerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,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.host) || (host === this.config.localHost) ? IsNull() : host,
isSuspended: false,
},
});
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/server/WellKnownServerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fastify.get('/.well-known/change-password', async (request, reply) => {
resource));

const fromAcct = (acct: Acct.Acct): FindOptionsWhere<MiUser> | number =>
!acct.host || acct.host === this.config.host.toLowerCase() ? {
!acct.host || acct.host === this.config.host.toLowerCase() || acct.host === this.config.localHost.toLowerCase() ? {
usernameLower: acct.username.toLowerCase(),
host: IsNull(),
isSuspended: false,
Expand All @@ -162,7 +162,7 @@ fastify.get('/.well-known/change-password', async (request, reply) => {
return;
}

const subject = `acct:${user.username}@${this.config.host}`;
const subject = `acct:${user.username}@${this.config.localHost}`;
const self = {
rel: 'self',
type: 'application/activity+json',
Expand Down
2 changes: 1 addition & 1 deletion packages/backend/src/server/web/FeedService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: 'Misskey',
description: `${user.notesCount} Notes, ${profile.followingVisibility === 'public' ? user.followingCount : '?'} Following, ${profile.followersVisibility === 'public' ? user.followersCount : '?'} Followers${profile.description ? ` · ${profile.description}` : ''}`,
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/server/web/HtmlTemplateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export class HtmlTemplateService {
infoImageUrl: this.meta.infoImageUrl ?? 'https://xn--931a.moe/assets/info.jpg',
notFoundImageUrl: this.meta.notFoundImageUrl ?? 'https://xn--931a.moe/assets/not-found.jpg',
instanceUrl: this.config.url,
localHost: this.config.localHost,
metaJson: htmlSafeJsonStringify(await this.metaEntityService.packDetailed(this.meta)),
now: Date.now(),
federationEnabled: this.meta.federation !== 'none',
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/server/web/views/_.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export type CommonData = MinimumCommonData & {
infoImageUrl: string;
notFoundImageUrl: string;
instanceUrl: string;
localHost: string;
now: number;
federationEnabled: boolean;
frontendViteFiles: ViteFiles | null;
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/server/web/views/base-embed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function BaseEmbed(props: PropsWithChildren<CommonProps<{
<meta name="theme-color-orig" content={props.themeColor ?? '#86b300'} />
<meta property="og:site_name" content={props.instanceName || 'Misskey'} />
<meta property="instance_url" content={props.instanceUrl} />
<meta property="local_host" content={props.localHost} />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover" />
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no" />
<link rel="icon" href={props.icon ?? '/favicon.ico'} />
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/server/web/views/base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function Layout(props: PropsWithChildren<CommonProps<{
<meta name="theme-color-orig" content={props.themeColor ?? '#86b300'} />
<meta property="og:site_name" content={props.instanceName || 'Misskey'} />
<meta property="instance_url" content={props.instanceUrl} />
<meta property="local_host" content={props.localHost} />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover" />
<meta name="format-detection" content="telephone=no,date=no,address=no,email=no,url=no" />
<link rel="icon" href={props.icon || '/favicon.ico'} />
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-embed/src/components/EmAcct.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-embed/src/components/EmMention.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend-embed/src/components/EmMfm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -347,7 +347,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
case 'mention': {
return [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,
})];
}
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend-shared/js/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@

// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const address = new URL(window.document.querySelector<HTMLMetaElement>('meta[property="instance_url"]')?.content || window.location.href);
const theLocalHost = window.document.querySelector<HTMLMetaElement>('meta[property="local_host"]')?.content;
const siteName = window.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 localHost = theLocalHost ?? host;
export const port = address.port;
export const apiUrl = window.location.origin + '/api';
export const wsOrigin = window.location.origin;
Expand Down
20 changes: 10 additions & 10 deletions packages/frontend/src/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -131,7 +131,7 @@ export function updateCurrentAccount(accountData: Misskey.entities.MeDetailed) {
for (const [key, value] of Object.entries(accountData)) {
($i[key as keyof typeof accountData] as any) = 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));
}
Expand All @@ -142,7 +142,7 @@ export function updateCurrentAccountPartial(accountData: Partial<Misskey.entitie
($i[key as keyof typeof accountData] as any) = 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));
}
Expand All @@ -152,7 +152,7 @@ export async function refreshCurrentAccount() {
const me = $i;
return fetchAccount($i.token, $i.id).then(updateCurrentAccount).catch(reason => {
if (reason === isAccountDeleted) {
removeAccount(host, me.id);
removeAccount(localHost, me.id);
if (Object.keys(store.s.accountTokens).length > 0) {
login(Object.values(store.s.accountTokens)[0]);
} else {
Expand Down Expand Up @@ -181,7 +181,7 @@ export async function login(token: AccountWithToken['token'], redirect?: string)
token,
}));

await addAccount(host, me, token);
await addAccount(localHost, me, token);

if (redirect) {
// 他のタブは再読み込みするだけ
Expand Down Expand Up @@ -296,7 +296,7 @@ export async function getAccountMenu(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);
Expand All @@ -319,7 +319,7 @@ export async function getAccountMenu(opts: {
action: () => {
getAccountWithSignupDialog().then(res => {
if (res != null) {
switchAccount(host, res.id);
switchAccount(localHost, res.id);
}
});
},
Expand All @@ -332,7 +332,7 @@ export async function getAccountMenu(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);
Expand All @@ -346,7 +346,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: () => {
Expand All @@ -365,7 +365,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: () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkAccountMoved.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/components/MkFollowButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { onBeforeUnmount, onMounted, ref } 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';
Expand Down Expand Up @@ -84,7 +84,7 @@ async function onClick() {
const isLoggedIn = await pleaseLogin({
openOnRemote: {
type: 'web',
path: `/@${props.user.username}@${props.user.host ?? host}`,
path: `/@${props.user.username}@${props.user.host ?? localHost}`,
},
});
if (!isLoggedIn) return;
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkMention.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Loading
Loading