Merge branch 'develop' into pr/ThatOneCalculator/8764
This commit is contained in:
		
						commit
						088d66a252
					
				
					 120 changed files with 501 additions and 365 deletions
				
			
		|  | @ -20,7 +20,7 @@ type Captcha = { | |||
| 	getResponse(id: string): string; | ||||
| }; | ||||
| 
 | ||||
| type CaptchaProvider = 'hcaptcha' | 'recaptcha'; | ||||
| type CaptchaProvider = 'hcaptcha' | 'recaptcha' | 'turnstile'; | ||||
| 
 | ||||
| type CaptchaContainer = { | ||||
| 	readonly [_ in CaptchaProvider]?: Captcha; | ||||
|  | @ -48,6 +48,7 @@ const variable = computed(() => { | |||
| 	switch (props.provider) { | ||||
| 		case 'hcaptcha': return 'hcaptcha'; | ||||
| 		case 'recaptcha': return 'grecaptcha'; | ||||
| 		case 'turnstile': return 'turnstile'; | ||||
| 	} | ||||
| }); | ||||
| 
 | ||||
|  | @ -57,6 +58,7 @@ const src = computed(() => { | |||
| 	switch (props.provider) { | ||||
| 		case 'hcaptcha': return 'https://js.hcaptcha.com/1/api.js?render=explicit&recaptchacompat=off'; | ||||
| 		case 'recaptcha': return 'https://www.recaptcha.net/recaptcha/api.js?render=explicit'; | ||||
| 		case 'turnstile': return 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit'; | ||||
| 	} | ||||
| }); | ||||
| 
 | ||||
|  |  | |||
|  | @ -90,7 +90,22 @@ function onDragover(ev: DragEvent) { | |||
| 	const isDriveFolder = ev.dataTransfer.types[0] === _DATA_TRANSFER_DRIVE_FOLDER_; | ||||
| 
 | ||||
| 	if (isFile || isDriveFile || isDriveFolder) { | ||||
| 		ev.dataTransfer.dropEffect = ev.dataTransfer.effectAllowed === 'all' ? 'copy' : 'move'; | ||||
| 		switch (ev.dataTransfer.effectAllowed) { | ||||
| 			case 'all': | ||||
| 			case 'uninitialized': | ||||
| 			case 'copy':  | ||||
| 			case 'copyLink':  | ||||
| 			case 'copyMove':  | ||||
| 				ev.dataTransfer.dropEffect = 'copy'; | ||||
| 				break; | ||||
| 			case 'linkMove': | ||||
| 			case 'move': | ||||
| 				ev.dataTransfer.dropEffect = 'move'; | ||||
| 				break; | ||||
| 			default: | ||||
| 				ev.dataTransfer.dropEffect = 'none'; | ||||
| 				break; | ||||
| 		} | ||||
| 	} else { | ||||
| 		ev.dataTransfer.dropEffect = 'none'; | ||||
| 	} | ||||
|  |  | |||
|  | @ -58,7 +58,22 @@ function onDragover(ev: DragEvent) { | |||
| 	const isDriveFolder = ev.dataTransfer.types[0] === _DATA_TRANSFER_DRIVE_FOLDER_; | ||||
| 
 | ||||
| 	if (isFile || isDriveFile || isDriveFolder) { | ||||
| 		ev.dataTransfer.dropEffect = ev.dataTransfer.effectAllowed === 'all' ? 'copy' : 'move'; | ||||
| 		switch (ev.dataTransfer.effectAllowed) { | ||||
| 			case 'all': | ||||
| 			case 'uninitialized': | ||||
| 			case 'copy':  | ||||
| 			case 'copyLink':  | ||||
| 			case 'copyMove':  | ||||
| 				ev.dataTransfer.dropEffect = 'copy'; | ||||
| 				break; | ||||
| 			case 'linkMove': | ||||
| 			case 'move': | ||||
| 				ev.dataTransfer.dropEffect = 'move'; | ||||
| 				break; | ||||
| 			default: | ||||
| 				ev.dataTransfer.dropEffect = 'none'; | ||||
| 				break; | ||||
| 		} | ||||
| 	} else { | ||||
| 		ev.dataTransfer.dropEffect = 'none'; | ||||
| 	} | ||||
|  |  | |||
|  | @ -196,7 +196,22 @@ function onDragover(ev: DragEvent): any { | |||
| 	const isDriveFile = ev.dataTransfer.types[0] === _DATA_TRANSFER_DRIVE_FILE_; | ||||
| 	const isDriveFolder = ev.dataTransfer.types[0] === _DATA_TRANSFER_DRIVE_FOLDER_; | ||||
| 	if (isFile || isDriveFile || isDriveFolder) { | ||||
| 		ev.dataTransfer.dropEffect = ev.dataTransfer.effectAllowed === 'all' ? 'copy' : 'move'; | ||||
| 		switch (ev.dataTransfer.effectAllowed) { | ||||
| 			case 'all': | ||||
| 			case 'uninitialized': | ||||
| 			case 'copy':  | ||||
| 			case 'copyLink':  | ||||
| 			case 'copyMove':  | ||||
| 				ev.dataTransfer.dropEffect = 'copy'; | ||||
| 				break; | ||||
| 			case 'linkMove': | ||||
| 			case 'move': | ||||
| 				ev.dataTransfer.dropEffect = 'move'; | ||||
| 				break; | ||||
| 			default: | ||||
| 				ev.dataTransfer.dropEffect = 'none'; | ||||
| 				break; | ||||
| 		} | ||||
| 	} else { | ||||
| 		ev.dataTransfer.dropEffect = 'none'; | ||||
| 	} | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ | |||
| 	</MkSwitch> | ||||
| 	<MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" class="_formBlock captcha" provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/> | ||||
| 	<MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" class="_formBlock captcha" provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/> | ||||
| 	<MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" class="_formBlock captcha" provider="turnstile" :sitekey="instance.turnstileSiteKey"/> | ||||
| 	<MkButton class="_formBlock" type="submit" :disabled="shouldDisableSubmitting" gradate data-cy-signup-submit>{{ i18n.ts.start }}</MkButton> | ||||
| </form> | ||||
| </template> | ||||
|  | @ -92,6 +93,7 @@ const host = toUnicode(config.host); | |||
| 
 | ||||
| let hcaptcha = $ref(); | ||||
| let recaptcha = $ref(); | ||||
| let turnstile = $ref(); | ||||
| 
 | ||||
| let username: string = $ref(''); | ||||
| let password: string = $ref(''); | ||||
|  | @ -106,12 +108,14 @@ let submitting: boolean = $ref(false); | |||
| let ToSAgreement: boolean = $ref(false); | ||||
| let hCaptchaResponse = $ref(null); | ||||
| let reCaptchaResponse = $ref(null); | ||||
| let turnstileResponse = $ref(null); | ||||
| 
 | ||||
| const shouldDisableSubmitting = $computed((): boolean => { | ||||
| 	return submitting || | ||||
| 		instance.tosUrl && !ToSAgreement || | ||||
| 		instance.enableHcaptcha && !hCaptchaResponse || | ||||
| 		instance.enableRecaptcha && !reCaptchaResponse || | ||||
| 		instance.enableTurnstile && !turnstileResponse || | ||||
| 		passwordRetypeState === 'not-match'; | ||||
| }); | ||||
| 
 | ||||
|  | @ -198,6 +202,7 @@ function onSubmit(): void { | |||
| 		invitationCode, | ||||
| 		'hcaptcha-response': hCaptchaResponse, | ||||
| 		'g-recaptcha-response': reCaptchaResponse, | ||||
| 		'turnstile-response': turnstileResponse, | ||||
| 	}).then(() => { | ||||
| 		if (instance.emailRequiredForSignup) { | ||||
| 			os.alert({ | ||||
|  | @ -222,6 +227,7 @@ function onSubmit(): void { | |||
| 		submitting = false; | ||||
| 		hcaptcha.reset?.(); | ||||
| 		recaptcha.reset?.(); | ||||
| 		turnstile.reset?.(); | ||||
| 
 | ||||
| 		os.alert({ | ||||
| 			type: 'error', | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| <XWindow :initial-width="640" :initial-height="402" :can-resize="true" :close-button="true"> | ||||
| 	<template #header> | ||||
| 		<i class="icon fa-brands fa-youtube" style="margin-right: 0.5em;"></i> | ||||
| 		<span>{{ title ?? 'Youtube Player' }}</span> | ||||
| 		<span>{{ title ?? 'YouTube Player' }}</span> | ||||
| 	</template> | ||||
| 
 | ||||
| 	<div class="poamfof"> | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| 				<option :value="null">{{ i18n.ts.none }} ({{ i18n.ts.notRecommended }})</option> | ||||
| 				<option value="hcaptcha">hCaptcha</option> | ||||
| 				<option value="recaptcha">reCAPTCHA</option> | ||||
| 				<option value="turnstile">Turnstile</option> | ||||
| 			</FormRadios> | ||||
| 
 | ||||
| 			<template v-if="provider === 'hcaptcha'"> | ||||
|  | @ -36,6 +37,20 @@ | |||
| 					<MkCaptcha provider="recaptcha" :sitekey="recaptchaSiteKey"/> | ||||
| 				</FormSlot> | ||||
| 			</template> | ||||
| 			<template v-else-if="provider === 'turnstile'"> | ||||
| 				<FormInput v-model="turnstileSiteKey" class="_formBlock"> | ||||
| 					<template #prefix><i class="fas fa-key"></i></template> | ||||
| 					<template #label>{{ i18n.ts.turnstileSiteKey }}</template> | ||||
| 				</FormInput> | ||||
| 				<FormInput v-model="turnstileSecretKey" class="_formBlock"> | ||||
| 					<template #prefix><i class="fas fa-key"></i></template> | ||||
| 					<template #label>{{ i18n.ts.turnstileSecretKey }}</template> | ||||
| 				</FormInput> | ||||
| 				<FormSlot class="_formBlock"> | ||||
| 					<template #label>{{ i18n.ts.preview }}</template> | ||||
| 					<MkCaptcha provider="turnstile" :sitekey="turnstileSiteKey || '1x00000000000000000000AA'"/> | ||||
| 				</FormSlot> | ||||
| 			</template> | ||||
| 
 | ||||
| 			<FormButton primary @click="save"><i class="fas fa-save"></i> {{ i18n.ts.save }}</FormButton> | ||||
| 		</div> | ||||
|  | @ -61,6 +76,8 @@ let hcaptchaSiteKey: string | null = $ref(null); | |||
| let hcaptchaSecretKey: string | null = $ref(null); | ||||
| let recaptchaSiteKey: string | null = $ref(null); | ||||
| let recaptchaSecretKey: string | null = $ref(null); | ||||
| let turnstileSiteKey: string | null = $ref(null); | ||||
| let turnstileSecretKey: string | null = $ref(null); | ||||
| 
 | ||||
| async function init() { | ||||
| 	const meta = await os.api('admin/meta'); | ||||
|  | @ -68,8 +85,10 @@ async function init() { | |||
| 	hcaptchaSecretKey = meta.hcaptchaSecretKey; | ||||
| 	recaptchaSiteKey = meta.recaptchaSiteKey; | ||||
| 	recaptchaSecretKey = meta.recaptchaSecretKey; | ||||
| 	turnstileSiteKey = meta.turnstileSiteKey; | ||||
| 	turnstileSecretKey = meta.turnstileSecretKey; | ||||
| 
 | ||||
| 	provider = meta.enableHcaptcha ? 'hcaptcha' : meta.enableRecaptcha ? 'recaptcha' : null; | ||||
| 	provider = meta.enableHcaptcha ? 'hcaptcha' : meta.enableRecaptcha ? 'recaptcha' : meta.enableTurnstile ? 'turnstile' : null; | ||||
| } | ||||
| 
 | ||||
| function save() { | ||||
|  | @ -80,6 +99,9 @@ function save() { | |||
| 		enableRecaptcha: provider === 'recaptcha', | ||||
| 		recaptchaSiteKey, | ||||
| 		recaptchaSecretKey, | ||||
| 		enableTurnstile: provider === 'turnstile', | ||||
| 		turnstileSiteKey, | ||||
| 		turnstileSecretKey, | ||||
| 	}).then(() => { | ||||
| 		fetchInstance(); | ||||
| 	}); | ||||
|  |  | |||
|  | @ -53,7 +53,7 @@ let view = $ref(null); | |||
| let el = $ref(null); | ||||
| let pageProps = $ref({}); | ||||
| let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail); | ||||
| let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha; | ||||
| let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha && !instance.enableTurnstile; | ||||
| let noEmailServer = !instance.enableEmail; | ||||
| let thereIsUnresolvedAbuseReport = $ref(false); | ||||
| let currentPage = $computed(() => router.currentRef.value.child); | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| 					<template #label>{{ i18n.ts.botProtection }}</template> | ||||
| 					<template v-if="enableHcaptcha" #suffix>hCaptcha</template> | ||||
| 					<template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template> | ||||
| 					<template v-else-if="enableTurnstile" #suffix>Turnstile</template> | ||||
| 					<template v-else #suffix>{{ i18n.ts.none }} ({{ i18n.ts.notRecommended }})</template> | ||||
| 
 | ||||
| 					<XBotProtection/> | ||||
|  | @ -120,6 +121,7 @@ import { definePageMetadata } from '@/scripts/page-metadata'; | |||
| let summalyProxy: string = $ref(''); | ||||
| let enableHcaptcha: boolean = $ref(false); | ||||
| let enableRecaptcha: boolean = $ref(false); | ||||
| let enableTurnstile: boolean = $ref(false); | ||||
| let sensitiveMediaDetection: string = $ref('none'); | ||||
| let sensitiveMediaDetectionSensitivity: number = $ref(0); | ||||
| let setSensitiveFlagAutomatically: boolean = $ref(false); | ||||
|  | @ -132,6 +134,7 @@ async function init() { | |||
| 	summalyProxy = meta.summalyProxy; | ||||
| 	enableHcaptcha = meta.enableHcaptcha; | ||||
| 	enableRecaptcha = meta.enableRecaptcha; | ||||
| 	enableTurnstile = meta.enableTurnstile; | ||||
| 	sensitiveMediaDetection = meta.sensitiveMediaDetection; | ||||
| 	sensitiveMediaDetectionSensitivity = | ||||
| 		meta.sensitiveMediaDetectionSensitivity === 'veryLow' ? 0 : | ||||
|  |  | |||
|  | @ -93,7 +93,22 @@ function onDragover(ev: DragEvent) { | |||
| 	const isDriveFile = ev.dataTransfer.types[0] === _DATA_TRANSFER_DRIVE_FILE_; | ||||
| 	if (isFile || isDriveFile) { | ||||
| 		ev.preventDefault(); | ||||
| 		ev.dataTransfer.dropEffect = ev.dataTransfer.effectAllowed === 'all' ? 'copy' : 'move'; | ||||
| 		switch (ev.dataTransfer.effectAllowed) { | ||||
| 			case 'all': | ||||
| 			case 'uninitialized': | ||||
| 			case 'copy':  | ||||
| 			case 'copyLink':  | ||||
| 			case 'copyMove':  | ||||
| 				ev.dataTransfer.dropEffect = 'copy'; | ||||
| 				break; | ||||
| 			case 'linkMove': | ||||
| 			case 'move': | ||||
| 				ev.dataTransfer.dropEffect = 'move'; | ||||
| 				break; | ||||
| 			default: | ||||
| 				ev.dataTransfer.dropEffect = 'none'; | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -154,7 +154,22 @@ function onDragover(ev: DragEvent) { | |||
| 	const isDriveFile = ev.dataTransfer.types[0] === _DATA_TRANSFER_DRIVE_FILE_; | ||||
| 
 | ||||
| 	if (isFile || isDriveFile) { | ||||
| 		ev.dataTransfer.dropEffect = ev.dataTransfer.effectAllowed === 'all' ? 'copy' : 'move'; | ||||
| 		switch (ev.dataTransfer.effectAllowed) { | ||||
| 			case 'all': | ||||
| 			case 'uninitialized': | ||||
| 			case 'copy':  | ||||
| 			case 'copyLink':  | ||||
| 			case 'copyMove':  | ||||
| 				ev.dataTransfer.dropEffect = 'copy'; | ||||
| 				break; | ||||
| 			case 'linkMove': | ||||
| 			case 'move': | ||||
| 				ev.dataTransfer.dropEffect = 'move'; | ||||
| 				break; | ||||
| 			default: | ||||
| 				ev.dataTransfer.dropEffect = 'none'; | ||||
| 				break; | ||||
| 		} | ||||
| 	} else { | ||||
| 		ev.dataTransfer.dropEffect = 'none'; | ||||
| 	} | ||||
|  |  | |||
|  | @ -78,6 +78,7 @@ async function save(): Promise<void> { | |||
| 		name, | ||||
| 		url, | ||||
| 		secret, | ||||
| 		webhookId: props.webhookId, | ||||
| 		on: events, | ||||
| 		active, | ||||
| 	}); | ||||
|  |  | |||
|  | @ -60,12 +60,6 @@ export function getNoteMenu(props: { | |||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	function toggleWatch(watch: boolean): void { | ||||
| 		os.apiWithDialog(watch ? 'notes/watching/create' : 'notes/watching/delete', { | ||||
| 			noteId: appearNote.id, | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	function toggleThreadMute(mute: boolean): void { | ||||
| 		os.apiWithDialog(mute ? 'notes/thread-muting/create' : 'notes/thread-muting/delete', { | ||||
| 			noteId: appearNote.id, | ||||
|  | @ -245,15 +239,6 @@ export function getNoteMenu(props: { | |||
| 				text: i18n.ts.clip, | ||||
| 				action: () => clip(), | ||||
| 			}, | ||||
| 			(appearNote.userId !== $i.id) ? statePromise.then(state => state.isWatching ? { | ||||
| 				icon: 'fas fa-eye-slash', | ||||
| 				text: i18n.ts.unwatch, | ||||
| 				action: () => toggleWatch(false), | ||||
| 			} : { | ||||
| 				icon: 'fas fa-eye', | ||||
| 				text: i18n.ts.watch, | ||||
| 				action: () => toggleWatch(true), | ||||
| 			}) : undefined, | ||||
| 			statePromise.then(state => state.isMutedThread ? { | ||||
| 				icon: 'fas fa-comment-slash', | ||||
| 				text: i18n.ts.unmuteThread, | ||||
|  | @ -312,7 +297,7 @@ export function getNoteMenu(props: { | |||
| 				}] | ||||
| 			: [] | ||||
| 			)] | ||||
| 		.filter(x => x !== undefined); | ||||
| 			.filter(x => x !== undefined); | ||||
| 	} else { | ||||
| 		menu = [{ | ||||
| 			icon: 'fas fa-copy', | ||||
|  | @ -329,7 +314,7 @@ export function getNoteMenu(props: { | |||
| 				window.open(appearNote.url || appearNote.uri, '_blank'); | ||||
| 			}, | ||||
| 		} : undefined] | ||||
| 		.filter(x => x !== undefined); | ||||
| 			.filter(x => x !== undefined); | ||||
| 	} | ||||
| 
 | ||||
| 	if (noteActions.length > 0) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue