hirsun-vuepress-theme-hope-plus
Version:
A light vuepress theme with tons of features and typewriter effect
221 lines (211 loc) • 7.28 kB
JavaScript
import { h, defineComponent, ref, computed, nextTick, onMounted } from 'vue';
import { F as FadeSlideY } from '../../FadeSlideY-2f12d3e9.js';
import { usePageFrontmatter, usePageData } from '@vuepress/client';
import { IconBase, keys, startsWith } from 'vuepress-shared/client';
import { a as useThemeLocaleData, b as useThemeData } from '../../themeData-51227756.js';
import { useStorage, useSessionStorage } from '@vueuse/core';
import { compareSync } from 'bcrypt-ts/browser';
import { isPlainObject } from '@vuepress/shared';
import '@vuepress/plugin-theme-data/client';
const LockIcon = () => h(
IconBase,
{ name: "lock" },
() => h("path", {
d: "M787.168 952.268H236.832c-30.395 0-55.033-24.638-55.033-55.033V429.45c0-30.395 24.638-55.034 55.033-55.034h82.55V264.35c0-106.38 86.238-192.618 192.618-192.618S704.618 157.97 704.618 264.35v110.066h82.55c30.395 0 55.033 24.639 55.033 55.034v467.785c0 30.395-24.639 55.033-55.033 55.033zM484.483 672.046v115.122h55.034V672.046c31.99-11.373 55.033-41.605 55.033-77.496 0-45.592-36.958-82.55-82.55-82.55s-82.55 36.958-82.55 82.55c0 35.89 23.042 66.123 55.033 77.496zM622.067 264.35c0-60.788-49.28-110.067-110.067-110.067s-110.067 49.28-110.067 110.067v110.066h220.135V264.35z"
})
);
LockIcon.displayName = "LockIcon";
var PasswordModal = defineComponent({
name: "PasswordModal",
props: {
/**
* Whether is fullscreen
*
* 是否是全屏
*/
full: Boolean
},
emits: ["verify"],
setup(props, { emit }) {
const frontmatter = usePageFrontmatter();
const themeLocale = useThemeLocaleData();
const password = ref("");
const hasTried = ref(false);
const remember = ref(false);
const locale = computed(() => themeLocale.value.encryptLocales);
let hintHandler = null;
const verify = () => {
if (hintHandler)
clearTimeout(hintHandler);
hasTried.value = false;
emit("verify", password.value, remember.value);
void nextTick().then(() => {
hasTried.value = true;
hintHandler = setTimeout(() => {
hasTried.value = false;
}, 1e3);
});
};
return () => h(
"div",
{
class: [
"vp-decrypt-layer",
{ expand: props.full || frontmatter.value["home"] }
]
},
h("div", { class: "vp-decrypt-modal" }, [
h(
"div",
{ class: ["vp-decrypt-hint", { tried: hasTried.value }] },
hasTried.value ? locale.value.errorHint : h(LockIcon, { "aria-label": locale.value.iconLabel })
),
h("div", { class: "vp-decrypt-input" }, [
h("input", {
type: "password",
value: password.value,
placeholder: locale.value.placeholder,
onInput: ({ target }) => {
password.value = target.value;
},
onKeydown: ({ key }) => {
if (key === "Enter")
verify();
}
})
]),
h("div", { class: "vp-remember-password" }, [
h("input", {
type: "checkbox",
value: remember.value,
onChange: () => remember.value = !remember.value
}),
locale.value.remember
]),
h(
"button",
{
type: "button",
class: "vp-decrypt-submit",
onClick: () => verify()
},
"OK"
)
])
);
}
});
const useEncryptData = () => {
const themeData = useThemeData();
return computed(() => themeData.value.encrypt || {});
};
const STORAGE_KEY$1 = "VUEPRESS_HOPE_GLOBAL_TOKEN";
const useGlobalEncrypt = () => {
const encryptData = useEncryptData();
const localToken = useStorage(STORAGE_KEY$1, "");
const sessionToken = useSessionStorage(STORAGE_KEY$1, "");
const isEncrypted = computed(() => {
const { global = false, admin = [] } = encryptData.value;
return global && admin.length > 0;
});
const isDecrypted = computed(() => {
if (isEncrypted.value) {
if (localToken.value)
return encryptData.value.admin.some(
(hash) => compareSync(localToken.value, hash)
);
if (sessionToken.value)
return encryptData.value.admin.some(
(hash) => compareSync(sessionToken.value, hash)
);
}
return false;
});
const validate = (inputToken, keep = false) => {
(keep ? localToken : sessionToken).value = inputToken;
};
return {
isEncrypted,
isDecrypted,
validate
};
};
const checkToken = (token = "", hash) => Boolean(token) && compareSync(token, hash);
const STORAGE_KEY = "VUEPRESS_HOPE_PATH_TOKEN";
const usePathEncrypt = () => {
const page = usePageData();
const encryptData = useEncryptData();
const localToken = useStorage(STORAGE_KEY, {});
const sessionToken = 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 matchedKeys = getPathMatchedKeys(path);
if (matchedKeys.length > 0) {
const { config = {} } = encryptData.value;
return {
isEncrypted: true,
isDecrypted: matchedKeys.some(
(key) => localToken.value[key] && config[key].some(
(token) => checkToken(localToken.value[key], token)
) || sessionToken.value[key] && config[key].some(
(token) => checkToken(sessionToken.value[key], token)
)
)
};
}
return {
isDecrypted: false,
isEncrypted: false
};
};
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].filter((token) => checkToken(inputToken, token))) {
(keep ? localToken : sessionToken).value[hitKey] = inputToken;
break;
}
};
return {
status,
getStatus,
validate
};
};
var GlobalEncrypt = defineComponent({
name: "GlobalEncrypt",
slots: Object,
setup(_props, { slots }) {
const { isDecrypted, isEncrypted, validate } = useGlobalEncrypt();
const isMounted = ref(false);
onMounted(() => {
isMounted.value = true;
});
return () => h(
FadeSlideY,
() => isEncrypted.value ? isMounted.value ? isDecrypted.value ? slots.default() : h(PasswordModal, { full: true, onVerify: validate }) : null : slots.default()
);
}
});
var LocalEncrypt = defineComponent({
name: "LocalEncrypt",
slots: Object,
setup(_props, { slots }) {
const { status, validate } = usePathEncrypt();
const isMounted = ref(false);
onMounted(() => {
isMounted.value = true;
});
return () => {
const { isEncrypted, isDecrypted } = status.value;
return isEncrypted ? isMounted.value ? isDecrypted ? slots.default() || null : h(PasswordModal, { full: true, onVerify: validate }) : null : slots.default() || null;
};
}
});
export { GlobalEncrypt, LocalEncrypt };
//# sourceMappingURL=export.js.map