parent
9936088200
commit
7b7faf1e84
9 changed files with 65 additions and 12 deletions
|
@ -957,6 +957,7 @@ _role:
|
||||||
gtlAvailable: "グローバルタイムラインの閲覧"
|
gtlAvailable: "グローバルタイムラインの閲覧"
|
||||||
ltlAvailable: "ローカルタイムラインの閲覧"
|
ltlAvailable: "ローカルタイムラインの閲覧"
|
||||||
canPublicNote: "パブリック投稿の許可"
|
canPublicNote: "パブリック投稿の許可"
|
||||||
|
canInvite: "インスタンス招待コードの発行"
|
||||||
driveCapacity: "ドライブ容量"
|
driveCapacity: "ドライブ容量"
|
||||||
antennaMax: "アンテナの作成可能数"
|
antennaMax: "アンテナの作成可能数"
|
||||||
_condition:
|
_condition:
|
||||||
|
|
|
@ -16,6 +16,7 @@ export type RoleOptions = {
|
||||||
gtlAvailable: boolean;
|
gtlAvailable: boolean;
|
||||||
ltlAvailable: boolean;
|
ltlAvailable: boolean;
|
||||||
canPublicNote: boolean;
|
canPublicNote: boolean;
|
||||||
|
canInvite: boolean;
|
||||||
driveCapacityMb: number;
|
driveCapacityMb: number;
|
||||||
antennaLimit: number;
|
antennaLimit: number;
|
||||||
};
|
};
|
||||||
|
@ -24,6 +25,7 @@ export const DEFAULT_ROLE: RoleOptions = {
|
||||||
gtlAvailable: true,
|
gtlAvailable: true,
|
||||||
ltlAvailable: true,
|
ltlAvailable: true,
|
||||||
canPublicNote: true,
|
canPublicNote: true,
|
||||||
|
canInvite: false,
|
||||||
driveCapacityMb: 100,
|
driveCapacityMb: 100,
|
||||||
antennaLimit: 5,
|
antennaLimit: 5,
|
||||||
};
|
};
|
||||||
|
@ -179,6 +181,7 @@ export class RoleService implements OnApplicationShutdown {
|
||||||
gtlAvailable: getOptionValues('gtlAvailable').some(x => x === true),
|
gtlAvailable: getOptionValues('gtlAvailable').some(x => x === true),
|
||||||
ltlAvailable: getOptionValues('ltlAvailable').some(x => x === true),
|
ltlAvailable: getOptionValues('ltlAvailable').some(x => x === true),
|
||||||
canPublicNote: getOptionValues('canPublicNote').some(x => x === true),
|
canPublicNote: getOptionValues('canPublicNote').some(x => x === true),
|
||||||
|
canInvite: getOptionValues('canInvite').some(x => x === true),
|
||||||
driveCapacityMb: Math.max(...getOptionValues('driveCapacityMb')),
|
driveCapacityMb: Math.max(...getOptionValues('driveCapacityMb')),
|
||||||
antennaLimit: Math.max(...getOptionValues('antennaLimit')),
|
antennaLimit: Math.max(...getOptionValues('antennaLimit')),
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,7 +37,7 @@ import * as ep___admin_federation_updateInstance from './endpoints/admin/federat
|
||||||
import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js';
|
import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js';
|
||||||
import * as ep___admin_getTableStats from './endpoints/admin/get-table-stats.js';
|
import * as ep___admin_getTableStats from './endpoints/admin/get-table-stats.js';
|
||||||
import * as ep___admin_getUserIps from './endpoints/admin/get-user-ips.js';
|
import * as ep___admin_getUserIps from './endpoints/admin/get-user-ips.js';
|
||||||
import * as ep___admin_invite from './endpoints/admin/invite.js';
|
import * as ep___invite from './endpoints/invite.js';
|
||||||
import * as ep___admin_promo_create from './endpoints/admin/promo/create.js';
|
import * as ep___admin_promo_create from './endpoints/admin/promo/create.js';
|
||||||
import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js';
|
import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js';
|
||||||
import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js';
|
import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js';
|
||||||
|
@ -371,7 +371,7 @@ const $admin_federation_updateInstance: Provider = { provide: 'ep:admin/federati
|
||||||
const $admin_getIndexStats: Provider = { provide: 'ep:admin/get-index-stats', useClass: ep___admin_getIndexStats.default };
|
const $admin_getIndexStats: Provider = { provide: 'ep:admin/get-index-stats', useClass: ep___admin_getIndexStats.default };
|
||||||
const $admin_getTableStats: Provider = { provide: 'ep:admin/get-table-stats', useClass: ep___admin_getTableStats.default };
|
const $admin_getTableStats: Provider = { provide: 'ep:admin/get-table-stats', useClass: ep___admin_getTableStats.default };
|
||||||
const $admin_getUserIps: Provider = { provide: 'ep:admin/get-user-ips', useClass: ep___admin_getUserIps.default };
|
const $admin_getUserIps: Provider = { provide: 'ep:admin/get-user-ips', useClass: ep___admin_getUserIps.default };
|
||||||
const $admin_invite: Provider = { provide: 'ep:admin/invite', useClass: ep___admin_invite.default };
|
const $invite: Provider = { provide: 'ep:invite', useClass: ep___invite.default };
|
||||||
const $admin_promo_create: Provider = { provide: 'ep:admin/promo/create', useClass: ep___admin_promo_create.default };
|
const $admin_promo_create: Provider = { provide: 'ep:admin/promo/create', useClass: ep___admin_promo_create.default };
|
||||||
const $admin_queue_clear: Provider = { provide: 'ep:admin/queue/clear', useClass: ep___admin_queue_clear.default };
|
const $admin_queue_clear: Provider = { provide: 'ep:admin/queue/clear', useClass: ep___admin_queue_clear.default };
|
||||||
const $admin_queue_deliverDelayed: Provider = { provide: 'ep:admin/queue/deliver-delayed', useClass: ep___admin_queue_deliverDelayed.default };
|
const $admin_queue_deliverDelayed: Provider = { provide: 'ep:admin/queue/deliver-delayed', useClass: ep___admin_queue_deliverDelayed.default };
|
||||||
|
@ -709,7 +709,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
|
||||||
$admin_getIndexStats,
|
$admin_getIndexStats,
|
||||||
$admin_getTableStats,
|
$admin_getTableStats,
|
||||||
$admin_getUserIps,
|
$admin_getUserIps,
|
||||||
$admin_invite,
|
$invite,
|
||||||
$admin_promo_create,
|
$admin_promo_create,
|
||||||
$admin_queue_clear,
|
$admin_queue_clear,
|
||||||
$admin_queue_deliverDelayed,
|
$admin_queue_deliverDelayed,
|
||||||
|
@ -1041,7 +1041,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
|
||||||
$admin_getIndexStats,
|
$admin_getIndexStats,
|
||||||
$admin_getTableStats,
|
$admin_getTableStats,
|
||||||
$admin_getUserIps,
|
$admin_getUserIps,
|
||||||
$admin_invite,
|
$invite,
|
||||||
$admin_promo_create,
|
$admin_promo_create,
|
||||||
$admin_queue_clear,
|
$admin_queue_clear,
|
||||||
$admin_queue_deliverDelayed,
|
$admin_queue_deliverDelayed,
|
||||||
|
|
|
@ -36,7 +36,7 @@ import * as ep___admin_federation_updateInstance from './endpoints/admin/federat
|
||||||
import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js';
|
import * as ep___admin_getIndexStats from './endpoints/admin/get-index-stats.js';
|
||||||
import * as ep___admin_getTableStats from './endpoints/admin/get-table-stats.js';
|
import * as ep___admin_getTableStats from './endpoints/admin/get-table-stats.js';
|
||||||
import * as ep___admin_getUserIps from './endpoints/admin/get-user-ips.js';
|
import * as ep___admin_getUserIps from './endpoints/admin/get-user-ips.js';
|
||||||
import * as ep___admin_invite from './endpoints/admin/invite.js';
|
import * as ep___invite from './endpoints/invite.js';
|
||||||
import * as ep___admin_promo_create from './endpoints/admin/promo/create.js';
|
import * as ep___admin_promo_create from './endpoints/admin/promo/create.js';
|
||||||
import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js';
|
import * as ep___admin_queue_clear from './endpoints/admin/queue/clear.js';
|
||||||
import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js';
|
import * as ep___admin_queue_deliverDelayed from './endpoints/admin/queue/deliver-delayed.js';
|
||||||
|
@ -368,7 +368,7 @@ const eps = [
|
||||||
['admin/get-index-stats', ep___admin_getIndexStats],
|
['admin/get-index-stats', ep___admin_getIndexStats],
|
||||||
['admin/get-table-stats', ep___admin_getTableStats],
|
['admin/get-table-stats', ep___admin_getTableStats],
|
||||||
['admin/get-user-ips', ep___admin_getUserIps],
|
['admin/get-user-ips', ep___admin_getUserIps],
|
||||||
['admin/invite', ep___admin_invite],
|
['invite', ep___invite],
|
||||||
['admin/promo/create', ep___admin_promo_create],
|
['admin/promo/create', ep___admin_promo_create],
|
||||||
['admin/queue/clear', ep___admin_queue_clear],
|
['admin/queue/clear', ep___admin_queue_clear],
|
||||||
['admin/queue/deliver-delayed', ep___admin_queue_deliverDelayed],
|
['admin/queue/deliver-delayed', ep___admin_queue_deliverDelayed],
|
||||||
|
|
|
@ -4,12 +4,12 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import type { RegistrationTicketsRepository } from '@/models/index.js';
|
import type { RegistrationTicketsRepository } from '@/models/index.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
import { RoleService } from '@/core/RoleService.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['admin'],
|
tags: ['meta'],
|
||||||
|
|
||||||
requireCredential: true,
|
requireCredential: true,
|
||||||
requireModerator: true,
|
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -39,9 +39,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
@Inject(DI.registrationTicketsRepository)
|
@Inject(DI.registrationTicketsRepository)
|
||||||
private registrationTicketsRepository: RegistrationTicketsRepository,
|
private registrationTicketsRepository: RegistrationTicketsRepository,
|
||||||
|
|
||||||
|
private roleService: RoleService,
|
||||||
private idService: IdService,
|
private idService: IdService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async () => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
|
const role = await this.roleService.getUserRoleOptions(me.id);
|
||||||
|
if (!me.isRoot && !role.canInvite) {
|
||||||
|
throw new Error('access denied');
|
||||||
|
}
|
||||||
|
|
||||||
const code = rndstr({
|
const code = rndstr({
|
||||||
length: 8,
|
length: 8,
|
||||||
chars: '2-9A-HJ-NP-Z', // [0-9A-Z] w/o [01IO] (32 patterns)
|
chars: '2-9A-HJ-NP-Z', // [0-9A-Z] w/o [01IO] (32 patterns)
|
|
@ -80,7 +80,7 @@ const menuDef = $computed(() => [{
|
||||||
action: lookup,
|
action: lookup,
|
||||||
}, ...(instance.disableRegistration ? [{
|
}, ...(instance.disableRegistration ? [{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
icon: 'ti ti-user',
|
icon: 'ti ti-user-plus',
|
||||||
text: i18n.ts.invite,
|
text: i18n.ts.invite,
|
||||||
action: invite,
|
action: invite,
|
||||||
}] : [])],
|
}] : [])],
|
||||||
|
@ -223,7 +223,7 @@ provideMetadataReceiver((info) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const invite = () => {
|
const invite = () => {
|
||||||
os.api('admin/invite').then(x => {
|
os.api('invite').then(x => {
|
||||||
os.alert({
|
os.alert({
|
||||||
type: 'info',
|
type: 'info',
|
||||||
text: x.code,
|
text: x.code,
|
||||||
|
|
|
@ -77,6 +77,19 @@
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
|
||||||
|
<template #suffix>{{ options_canInvite_useDefault ? i18n.ts._role.useBaseValue : (options_canInvite_value ? i18n.ts.yes : i18n.ts.no) }}</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSwitch v-model="options_canInvite_useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkSwitch v-model="options_canInvite_value" :disabled="options_canInvite_useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||||
<template #suffix>{{ options_driveCapacityMb_useDefault ? i18n.ts._role.useBaseValue : (options_driveCapacityMb_value + 'MB') }}</template>
|
<template #suffix>{{ options_driveCapacityMb_useDefault ? i18n.ts._role.useBaseValue : (options_driveCapacityMb_value + 'MB') }}</template>
|
||||||
|
@ -160,6 +173,8 @@ let options_ltlAvailable_useDefault = $ref(role?.options?.ltlAvailable?.useDefau
|
||||||
let options_ltlAvailable_value = $ref(role?.options?.ltlAvailable?.value ?? false);
|
let options_ltlAvailable_value = $ref(role?.options?.ltlAvailable?.value ?? false);
|
||||||
let options_canPublicNote_useDefault = $ref(role?.options?.canPublicNote?.useDefault ?? true);
|
let options_canPublicNote_useDefault = $ref(role?.options?.canPublicNote?.useDefault ?? true);
|
||||||
let options_canPublicNote_value = $ref(role?.options?.canPublicNote?.value ?? false);
|
let options_canPublicNote_value = $ref(role?.options?.canPublicNote?.value ?? false);
|
||||||
|
let options_canInvite_useDefault = $ref(role?.options?.canInvite?.useDefault ?? true);
|
||||||
|
let options_canInvite_value = $ref(role?.options?.canInvite?.value ?? false);
|
||||||
let options_driveCapacityMb_useDefault = $ref(role?.options?.driveCapacityMb?.useDefault ?? true);
|
let options_driveCapacityMb_useDefault = $ref(role?.options?.driveCapacityMb?.useDefault ?? true);
|
||||||
let options_driveCapacityMb_value = $ref(role?.options?.driveCapacityMb?.value ?? 0);
|
let options_driveCapacityMb_value = $ref(role?.options?.driveCapacityMb?.value ?? 0);
|
||||||
let options_antennaLimit_useDefault = $ref(role?.options?.antennaLimit?.useDefault ?? true);
|
let options_antennaLimit_useDefault = $ref(role?.options?.antennaLimit?.useDefault ?? true);
|
||||||
|
@ -176,6 +191,7 @@ function getOptions() {
|
||||||
gtlAvailable: { useDefault: options_gtlAvailable_useDefault, value: options_gtlAvailable_value },
|
gtlAvailable: { useDefault: options_gtlAvailable_useDefault, value: options_gtlAvailable_value },
|
||||||
ltlAvailable: { useDefault: options_ltlAvailable_useDefault, value: options_ltlAvailable_value },
|
ltlAvailable: { useDefault: options_ltlAvailable_useDefault, value: options_ltlAvailable_value },
|
||||||
canPublicNote: { useDefault: options_canPublicNote_useDefault, value: options_canPublicNote_value },
|
canPublicNote: { useDefault: options_canPublicNote_useDefault, value: options_canPublicNote_value },
|
||||||
|
canInvite: { useDefault: options_canInvite_useDefault, value: options_canInvite_value },
|
||||||
driveCapacityMb: { useDefault: options_driveCapacityMb_useDefault, value: options_driveCapacityMb_value },
|
driveCapacityMb: { useDefault: options_driveCapacityMb_useDefault, value: options_driveCapacityMb_value },
|
||||||
antennaLimit: { useDefault: options_antennaLimit_useDefault, value: options_antennaLimit_value },
|
antennaLimit: { useDefault: options_antennaLimit_useDefault, value: options_antennaLimit_value },
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,14 @@
|
||||||
</MkSwitch>
|
</MkSwitch>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>{{ i18n.ts._role._options.canInvite }}</template>
|
||||||
|
<template #suffix>{{ options_canInvite ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||||
|
<MkSwitch v-model="options_canInvite">
|
||||||
|
<template #label>{{ i18n.ts.enable }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
<template #label>{{ i18n.ts._role._options.driveCapacity }}</template>
|
||||||
<template #suffix>{{ options_driveCapacityMb }}MB</template>
|
<template #suffix>{{ options_driveCapacityMb }}MB</template>
|
||||||
|
@ -81,6 +89,7 @@ const roles = await os.api('admin/roles/list');
|
||||||
let options_gtlAvailable = $ref(instance.baseRole.gtlAvailable);
|
let options_gtlAvailable = $ref(instance.baseRole.gtlAvailable);
|
||||||
let options_ltlAvailable = $ref(instance.baseRole.ltlAvailable);
|
let options_ltlAvailable = $ref(instance.baseRole.ltlAvailable);
|
||||||
let options_canPublicNote = $ref(instance.baseRole.canPublicNote);
|
let options_canPublicNote = $ref(instance.baseRole.canPublicNote);
|
||||||
|
let options_canInvite = $ref(instance.baseRole.canInvite);
|
||||||
let options_driveCapacityMb = $ref(instance.baseRole.driveCapacityMb);
|
let options_driveCapacityMb = $ref(instance.baseRole.driveCapacityMb);
|
||||||
let options_antennaLimit = $ref(instance.baseRole.antennaLimit);
|
let options_antennaLimit = $ref(instance.baseRole.antennaLimit);
|
||||||
|
|
||||||
|
@ -90,6 +99,7 @@ async function updateBaseRole() {
|
||||||
gtlAvailable: options_gtlAvailable,
|
gtlAvailable: options_gtlAvailable,
|
||||||
ltlAvailable: options_ltlAvailable,
|
ltlAvailable: options_ltlAvailable,
|
||||||
canPublicNote: options_canPublicNote,
|
canPublicNote: options_canPublicNote,
|
||||||
|
canInvite: options_canInvite,
|
||||||
driveCapacityMb: options_driveCapacityMb,
|
driveCapacityMb: options_driveCapacityMb,
|
||||||
antennaLimit: options_antennaLimit,
|
antennaLimit: options_antennaLimit,
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as os from '@/os';
|
||||||
import { instance } from '@/instance';
|
import { instance } from '@/instance';
|
||||||
import { host } from '@/config';
|
import { host } from '@/config';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
|
||||||
export function openInstanceMenu(ev: MouseEvent) {
|
export function openInstanceMenu(ev: MouseEvent) {
|
||||||
os.popupMenu([{
|
os.popupMenu([{
|
||||||
|
@ -46,7 +47,23 @@ export function openInstanceMenu(ev: MouseEvent) {
|
||||||
to: '/clicker',
|
to: '/clicker',
|
||||||
text: '🍪👈',
|
text: '🍪👈',
|
||||||
icon: 'ti ti-cookie',
|
icon: 'ti ti-cookie',
|
||||||
}],
|
}, ($i && ($i.isRoot || $i.role.canInvite) && instance.disableRegistration) ? {
|
||||||
|
text: i18n.ts.invite,
|
||||||
|
icon: 'ti ti-user-plus',
|
||||||
|
action: () => {
|
||||||
|
os.api('invite').then(x => {
|
||||||
|
os.alert({
|
||||||
|
type: 'info',
|
||||||
|
text: x.code,
|
||||||
|
});
|
||||||
|
}).catch(err => {
|
||||||
|
os.alert({
|
||||||
|
type: 'error',
|
||||||
|
text: err,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
} : undefined],
|
||||||
}, null, {
|
}, null, {
|
||||||
text: i18n.ts.help,
|
text: i18n.ts.help,
|
||||||
icon: 'ti ti-question-circle',
|
icon: 'ti ti-question-circle',
|
||||||
|
|
Loading…
Reference in a new issue