Compare commits

...

10 Commits

Author SHA1 Message Date
sharevb
9e247ae65b
Merge 97544530c9 into e1b4f9aafe 2024-08-08 00:20:59 +09:00
Diego Fabricio
e1b4f9aafe
feat(lorem-ipsum): add button to refresh text lorem-ipsum (#1213)
Co-authored-by: Diego Guzmán <diego.guzman@caces.gob.ec>
2024-08-07 09:22:08 +02:00
sharevb
97544530c9
Merge branch 'main' into feat/htpasswd 2024-04-14 20:28:32 +02:00
ShareVB
0de51a2dea chore(github workflows): ci and e2e tests: try updating to node 20 2024-04-14 20:27:30 +02:00
sharevb
3b7b0a45e6 feat(htpasswd generator): allow salt rounds input (if bcrypt) 2024-04-14 14:43:40 +02:00
sharevb
3a0b612239 feat(new tool): htpasswd generator
Fix #430 and #807
2024-02-25 14:19:09 +01:00
ShareVB
e073b2babf chore: fix deps 2024-02-18 12:01:33 +01:00
sharevb
83832f3e2c feat(TextareaCopyable): word-wrap prop
Add word-wrap property (to allow presenting long public keys)
2024-02-18 11:39:13 +01:00
sharevb
ee40ba1439 chore: prepare sshpk for cert/key/sshkeys related tools 2024-02-18 11:39:13 +01:00
sharevb
3f32990499 chore: prepare sshpk for cert/key/sshkeys related tools 2024-02-18 11:38:29 +01:00
8 changed files with 728 additions and 7 deletions

View File

@ -47,6 +47,7 @@
"@vueuse/core": "^10.3.0",
"@vueuse/head": "^1.0.0",
"@vueuse/router": "^10.0.0",
"apache-md5": "^1.1.8",
"bcryptjs": "^2.4.3",
"change-case": "^4.1.2",
"colord": "^2.9.3",
@ -82,6 +83,7 @@
"plausible-tracker": "^0.3.8",
"qrcode": "^1.5.1",
"sql-formatter": "^13.0.0",
"sshpk": "^1.18.0",
"ua-parser-js": "^1.0.35",
"ulid": "^2.3.0",
"unicode-emoji-json": "^0.4.0",
@ -111,6 +113,7 @@
"@types/node": "^18.15.11",
"@types/node-forge": "^1.3.2",
"@types/qrcode": "^1.5.0",
"@types/sshpk": "^1.17.4",
"@types/ua-parser-js": "^0.7.36",
"@types/uuid": "^9.0.0",
"@unocss/eslint-config": "^0.57.0",
@ -132,6 +135,7 @@
"unplugin-icons": "^0.17.0",
"unplugin-vue-components": "^0.25.0",
"vite": "^4.4.9",
"vite-plugin-node-polyfills": "^0.21.0",
"vite-plugin-pwa": "^0.16.0",
"vite-plugin-vue-markdown": "^0.23.5",
"vite-svg-loader": "^4.0.0",

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@ const props = withDefaults(
language?: string
copyPlacement?: 'top-right' | 'bottom-right' | 'outside' | 'none'
copyMessage?: string
wordWrap?: boolean
}>(),
{
followHeightOf: null,
@ -47,7 +48,7 @@ const tooltipText = computed(() => isJustCopied.value ? 'Copied!' : copyMessage.
:style="height ? `min-height: ${height - 40 /* card padding */ + 10 /* negative margin compensation */}px` : ''"
>
<n-config-provider :hljs="hljs">
<n-code :code="value" :language="language" :trim="false" data-test-id="area-content" />
<n-code :code="value" :language="language" :word-wrap="wordWrap" :trim="false" data-test-id="area-content" />
</n-config-provider>
</n-scrollbar>
<div absolute right-10px top-10px>

View File

@ -0,0 +1,60 @@
<script setup lang="ts">
import { hashSync } from 'bcryptjs';
import md5 from 'apache-md5';
import TextareaCopyable from '@/components/TextareaCopyable.vue';
const username = ref('');
const password = ref('');
const hashMethod = ref('bcrypt');
const saltCount = ref(10);
const htpasswd = computed(() => {
if (username.value === '' || password.value === '') {
return '# username and password must not be empty';
}
let hash;
if (hashMethod.value === 'md5') {
hash = md5(password.value);
}
else {
hash = hashSync(password.value, saltCount.value);
}
return `${username.value}:${hash}`;
});
</script>
<template>
<div>
<c-input-text
v-model:value="username"
label="Username"
placeholder="Your username..."
clearable raw-text mb-5
/>
<c-input-text
v-model:value="password"
label="Password"
placeholder="Your password..."
clearable
raw-text
mb-2
type="password"
/>
<c-select
v-model:value="hashMethod"
label="Hash method:"
:options="['bcrypt', 'md5']"
/>
<n-form-item v-if="hashMethod === 'bcrypt'" label="Salt count: " label-placement="left" label-width="120">
<n-input-number v-model:value="saltCount" placeholder="Salt rounds..." :max="100" :min="0" w-full />
</n-form-item>
<n-divider />
<n-form-item label="htpasswd content:">
<TextareaCopyable :value="htpasswd" />
</n-form-item>
</div>
</template>

View File

@ -0,0 +1,12 @@
import { PasswordRound } from '@vicons/material';
import { defineTool } from '../tool';
export const tool = defineTool({
name: 'Htpasswd/htaccess generator',
path: '/htpasswd-generator',
description: 'htpassword/htaccess user/password generator',
keywords: ['htpasswd', 'htaccess', 'bcrypt', 'password'],
component: () => import('./htpasswd-generator.vue'),
icon: PasswordRound,
createdAt: new Date('2024-02-20'),
});

View File

@ -5,6 +5,7 @@ import { tool as basicAuthGenerator } from './basic-auth-generator';
import { tool as asciiTextDrawer } from './ascii-text-drawer';
import { tool as textToUnicode } from './text-to-unicode';
import { tool as htpasswdGenerator } from './htpasswd-generator';
import { tool as safelinkDecoder } from './safelink-decoder';
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
import { tool as numeronymGenerator } from './numeronym-generator';
@ -117,6 +118,7 @@ export const toolsByCategory: ToolCategory[] = [
urlParser,
deviceInformation,
basicAuthGenerator,
htpasswdGenerator,
metaTagGenerator,
otpCodeGeneratorAndValidator,
mimeTypes,

View File

@ -2,6 +2,7 @@
import { generateLoremIpsum } from './lorem-ipsum-generator.service';
import { useCopy } from '@/composable/copy';
import { randIntFromInterval } from '@/utils/random';
import { computedRefreshable } from '@/composable/computedRefreshable';
const paragraphs = ref(1);
const sentences = ref([3, 8]);
@ -9,7 +10,7 @@ const words = ref([8, 15]);
const startWithLoremIpsum = ref(true);
const asHTML = ref(false);
const loremIpsumText = computed(() =>
const [loremIpsumText, refreshLoremIpsum] = computedRefreshable(() =>
generateLoremIpsum({
paragraphCount: paragraphs.value,
asHTML: asHTML.value,
@ -18,6 +19,7 @@ const loremIpsumText = computed(() =>
startWithLoremIpsum: startWithLoremIpsum.value,
}),
);
const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' });
</script>
@ -41,10 +43,13 @@ const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to
<c-input-text :value="loremIpsumText" multiline placeholder="Your lorem ipsum..." readonly mt-5 rows="5" />
<div mt-5 flex justify-center>
<div mt-5 flex justify-center gap-3>
<c-button autofocus @click="copy()">
Copy
</c-button>
<c-button @click="refreshLoremIpsum">
Refresh
</c-button>
</div>
</c-card>
</template>

View File

@ -1,5 +1,6 @@
import { resolve } from 'node:path';
import { URL, fileURLToPath } from 'node:url';
import { nodePolyfills } from 'vite-plugin-node-polyfills';
import VueI18n from '@intlify/unplugin-vue-i18n/vite';
import vue from '@vitejs/plugin-vue';
@ -97,6 +98,7 @@ export default defineConfig({
resolvers: [NaiveUiResolver(), IconsResolver({ prefix: 'icon' })],
}),
Unocss(),
nodePolyfills(),
],
base: baseUrl,
resolve: {