UNPKG

vuepress-theme-hope

Version:

A light vuepress theme with tons of features

207 lines (199 loc) 7.08 kB
import { l as useData$1, u as useTheme } from "../../PageInfo-BBtUekHB.js"; import { n as MainFadeInUpTransition_default, t as PageTitle_default } from "../../PageTitle-aWhvdXk3.js"; import { t as LockIcon } from "../../LockIcon-CC7XxocU.js"; import { useSessionStorage, useStorage } from "@vueuse/core"; import { computed, defineComponent, h, nextTick, onMounted, ref } from "vue"; import { usePage } from "vuepress/client"; import { isPlainObject, keys, startsWith } from "@vuepress/helper/client"; import "../../client/styles/encrypt/password-modal.scss"; import { compareSync } from "bcrypt-ts/browser"; //#region src/client/components/encrypt/PasswordModal.ts var PasswordModal_default = defineComponent({ name: "PasswordModal", props: { /** Password hint */ hint: String, /** * Whether is fullscreen * * 是否是全屏 */ full: Boolean, /** * Whether to show title * * 是否显示标题 */ showTitle: Boolean }, emits: ["verify"], setup(props, { emit }) { const { frontmatter, themeLocale } = useData$1(); const password = ref(""); const hasTried = ref(false); const remember = ref(false); const encryptLocale = computed(() => themeLocale.value.encryptLocales); let hintHandler = null; const verify = () => { if (hintHandler) clearTimeout(hintHandler); hasTried.value = false; emit("verify", password.value, remember.value); nextTick().then(() => { hasTried.value = true; hintHandler = setTimeout(() => { hasTried.value = false; }, 1e3); }); }; return () => h("div", { class: ["vp-decrypt-layer", { expand: props.full || frontmatter.value.home }] }, [props.showTitle ? h(PageTitle_default) : null, h("div", { class: "vp-decrypt-modal" }, [ h("div", { class: ["vp-decrypt-hint", { tried: hasTried.value }] }, hasTried.value ? encryptLocale.value.errorHint : h(LockIcon, { "aria-label": encryptLocale.value.iconLabel })), props.hint ? h("div", { class: "vp-decrypt-hint" }, props.hint) : null, h("div", { class: "vp-decrypt-input" }, [h("input", { type: "password", value: password.value, placeholder: encryptLocale.value.placeholder, onInput: ({ target }) => { password.value = target.value; }, onKeydown: ({ key }) => { if (key === "Enter") verify(); } })]), h("div", { class: "vp-remember-password" }, [h("input", { id: "remember-password", type: "checkbox", value: remember.value, onChange: () => { remember.value = !remember.value; } }), h("label", { for: "remember-password" }, encryptLocale.value.remember)]), h("button", { type: "button", class: "vp-decrypt-submit", onClick: () => { verify(); } }, "OK") ])]); } }); //#endregion //#region src/client/composables/encrypt/useEncryptConfig.ts const useEncryptConfig = () => { const theme = useTheme(); return computed(() => theme.value.encrypt); }; //#endregion //#region src/client/composables/encrypt/useGlobalEncrypt.ts const STORAGE_KEY$1 = "VUEPRESS_HOPE_GLOBAL_TOKEN"; const useGlobalEncrypt = () => { const encryptData = useEncryptConfig(); const storageToken = useStorage(STORAGE_KEY$1, ""); const sessionToken = useSessionStorage(STORAGE_KEY$1, ""); const status = computed(() => { const { global = false, admin } = encryptData.value; const isEncrypted = global && Boolean(admin?.tokens.length); return { isEncrypted, isLocked: isEncrypted ? storageToken.value ? encryptData.value.admin.tokens.every((hash) => !compareSync(storageToken.value, hash)) : encryptData.value.admin.tokens.every((hash) => !compareSync(sessionToken.value, hash)) : false, hint: admin?.hint ?? "" }; }); const validate = (inputToken, keep = false) => { (keep ? storageToken : sessionToken).value = inputToken; }; return { status, validate }; }; //#endregion //#region src/client/components/encrypt/GlobalEncrypt.ts var GlobalEncrypt_default = defineComponent({ name: "GlobalEncrypt", slots: Object, setup(_props, { slots }) { const { status, validate } = useGlobalEncrypt(); const isMounted = ref(false); onMounted(() => { isMounted.value = true; }); return () => { const { isEncrypted, isLocked, hint } = status.value; return h(MainFadeInUpTransition_default, () => isEncrypted ? isMounted.value ? isLocked ? h(PasswordModal_default, { full: true, hint, onVerify: validate }) : slots.default() : null : slots.default()); }; } }); //#endregion //#region src/client/utils/encrypt/isTokenMatched.ts const isTokenMatched = (hash, token) => Boolean(token) && compareSync(token, hash); //#endregion //#region src/client/composables/encrypt/usePathEncrypt.ts const STORAGE_KEY = "VUEPRESS_HOPE_PATH_TOKEN"; const usePathEncrypt = () => { const page = usePage(); const encryptData = useEncryptConfig(); const localTokenConfig = useStorage(STORAGE_KEY, {}); const sessionTokenConfig = useSessionStorage(STORAGE_KEY, {}); const getPathMatchedKeys = (path) => isPlainObject(encryptData.value.config) ? keys(encryptData.value.config).filter((key) => startsWith(decodeURI(path), key)).sort((a, b) => b.length - a.length) : []; const getStatus = (path) => { const { config = {} } = encryptData.value; const matchedKeys = getPathMatchedKeys(path); if (matchedKeys.length > 0) { const firstKeyWithHint = matchedKeys.find((key) => config[key].hint); return { isEncrypted: true, isLocked: matchedKeys.some((key) => (localTokenConfig.value[key] ? config[key].tokens.every((token) => !isTokenMatched(token, localTokenConfig.value[key])) : true) && (sessionTokenConfig.value[key] ? config[key].tokens.every((token) => !isTokenMatched(token, sessionTokenConfig.value[key])) : true)), hint: firstKeyWithHint ? config[firstKeyWithHint].hint : "" }; } return { isEncrypted: false, isLocked: false, hint: "" }; }; const status = computed(() => getStatus(page.value.path)); const validate = (inputToken, keep = false) => { const { config = {} } = encryptData.value; const matchedKeys = getPathMatchedKeys(page.value.path); for (const hitKey of matchedKeys) if (config[hitKey].tokens.some((token) => isTokenMatched(token, inputToken))) { (keep ? localTokenConfig : sessionTokenConfig).value[hitKey] = inputToken; break; } }; return { status, getStatus, validate }; }; //#endregion //#region src/client/components/encrypt/LocalEncrypt.ts var LocalEncrypt_default = defineComponent({ name: "LocalEncrypt", slots: Object, setup(_props, { slots }) { const { status, validate } = usePathEncrypt(); const isMounted = ref(false); onMounted(() => { isMounted.value = true; }); return () => { const { isEncrypted, isLocked, hint } = status.value; return isEncrypted ? isMounted.value ? isLocked ? h(PasswordModal_default, { showTitle: true, full: true, hint, onVerify: validate }) : slots.default() : null : slots.default(); }; } }); //#endregion export { GlobalEncrypt_default as GlobalEncrypt, LocalEncrypt_default as LocalEncrypt }; //# sourceMappingURL=encrypt.js.map