Compare commits

..

7 Commits

Author SHA1 Message Date
Corentin Thomasset
eb2755c8ae chore(release): 2.2.0 2022-04-19 00:13:32 +02:00
Corentin Thomasset
2b38d6f81e feat(new-tool): url parser 2022-04-19 00:12:44 +02:00
Corentin Thomasset
ed9046d3e1 fix(sider-footer): fixed commit sha url 2022-04-18 18:27:52 +02:00
Corentin Thomasset
3f8c345981 chore(release): 2.1.0 2022-04-18 18:24:16 +02:00
Corentin Thomasset
277bd5f0da feat(new-tool): device information 2022-04-18 18:22:47 +02:00
Corentin Thomasset
09abffbcf9 refactor(menu): removed burger menu icon tooltip 2022-04-18 10:19:19 +02:00
Corentin Thomasset
6d5856fa93 feat(new-tool): bcrypt 2022-04-18 10:17:39 +02:00
11 changed files with 455 additions and 25 deletions

View File

@@ -2,6 +2,31 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [2.2.0](https://github.com/CorentinTh/it-tools/compare/v2.1.0...v2.2.0) (2022-04-18)
### Features
* **new-tool:** url parser ([2b38d6f](https://github.com/CorentinTh/it-tools/commit/2b38d6f81e34845f896b858513e35209cba29f98))
### Bug Fixes
* **sider-footer:** fixed commit sha url ([ed9046d](https://github.com/CorentinTh/it-tools/commit/ed9046d3e1f5a7dc01c722ed139a2ae477a2d48f))
## [2.1.0](https://github.com/CorentinTh/it-tools/compare/v2.0.2...v2.1.0) (2022-04-18)
### Features
* **new-tool:** bcrypt ([6d5856f](https://github.com/CorentinTh/it-tools/commit/6d5856fa93d1ffbf71856c75adc24ad87dc4b49b))
* **new-tool:** device information ([277bd5f](https://github.com/CorentinTh/it-tools/commit/277bd5f0da359fd54c5164b376007d182a9fabde))
### Refactors
* **menu:** removed burger menu icon tooltip ([09abffb](https://github.com/CorentinTh/it-tools/commit/09abffbcf9b09cb5adc34f8754b019d0c8b60854))
### [2.0.2](https://github.com/CorentinTh/it-tools/compare/v2.0.1...v2.0.2) (2022-04-18)

28
package-lock.json generated
View File

@@ -1,18 +1,19 @@
{
"name": "it-tools",
"version": "2.0.2",
"version": "2.2.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "it-tools",
"version": "2.0.2",
"version": "2.2.0",
"dependencies": {
"@it-tools/bip39": "^0.0.4",
"@vicons/material": "^0.12.0",
"@vicons/tabler": "^0.12.0",
"@vueuse/core": "^8.2.1",
"@vueuse/head": "^0.7.5",
"bcryptjs": "^2.4.3",
"change-case": "^4.1.2",
"colord": "^2.9.2",
"cron-validator": "^1.3.1",
@@ -31,6 +32,7 @@
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.0",
"@types/bcryptjs": "^2.4.2",
"@types/crypto-js": "^4.1.1",
"@types/jsdom": "^16.2.14",
"@types/node": "^16.11.25",
@@ -2112,6 +2114,12 @@
"node": ">=10.13.0"
}
},
"node_modules/@types/bcryptjs": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz",
"integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==",
"dev": true
},
"node_modules/@types/chai": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz",
@@ -3173,6 +3181,11 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/bcryptjs": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
"integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
},
"node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -12690,6 +12703,12 @@
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
"dev": true
},
"@types/bcryptjs": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz",
"integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==",
"dev": true
},
"@types/chai": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz",
@@ -13526,6 +13545,11 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"bcryptjs": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
"integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "it-tools",
"version": "2.0.2",
"version": "2.2.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
@@ -18,6 +18,7 @@
"@vicons/tabler": "^0.12.0",
"@vueuse/core": "^8.2.1",
"@vueuse/head": "^0.7.5",
"bcryptjs": "^2.4.3",
"change-case": "^4.1.2",
"colord": "^2.9.2",
"cron-validator": "^1.3.1",
@@ -36,6 +37,7 @@
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.0",
"@types/bcryptjs": "^2.4.2",
"@types/crypto-js": "^4.1.1",
"@types/jsdom": "^16.2.14",
"@types/node": "^16.11.25",

View File

@@ -98,7 +98,7 @@ const m = toolsByCategory.map(category => ({
rel="noopener"
type="primary"
depth="3"
:href="`https://github.com/CorentinTh/it-tools/tree/v${commitSha}`"
:href="`https://github.com/CorentinTh/it-tools/tree/${commitSha}`"
>
{{ commitSha }}
</n-button>
@@ -122,26 +122,19 @@ const m = toolsByCategory.map(category => ({
<template #content>
<div class="navigation">
<n-tooltip
trigger="hover"
placement="bottom-start"
<n-button
:size="styleStore.isSmallScreen ? 'medium' : 'large'"
circle
quaternary
aria-label="Toogle menu"
@click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed"
>
<template #trigger>
<n-button
:size="styleStore.isSmallScreen ? 'medium' : 'large'"
circle
quaternary
aria-label="Toogle menu"
@click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed"
>
<n-icon
size="25"
:component="Menu2"
/>
</n-button>
</template>
Toggle menu
</n-tooltip>
<n-icon
size="25"
:component="Menu2"
/>
</n-button>
<router-link
to="/"

118
src/tools/bcrypt/bcrypt.vue Normal file
View File

@@ -0,0 +1,118 @@
<template>
<n-card title="Hash">
<n-form label-width="120">
<n-form-item
label="Your string: "
label-placement="left"
>
<n-input
v-model:value="input"
placeholder="Your string to bcrypt..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
/>
</n-form-item>
<n-form-item
label="Salt count: "
label-placement="left"
>
<n-input-number
v-model:value="saltCount"
placeholder="Salt rounds..."
:max="10"
:min="0"
style="width: 100%;"
/>
</n-form-item>
<n-input
:value="hashed"
readonly
style="text-align: center;"
/>
</n-form>
<br>
<n-space justify="center">
<n-button
secondary
@click="copy"
>
Copy hash
</n-button>
</n-space>
</n-card>
<br>
<n-card title="Compare string with hash">
<n-form label-width="120">
<n-form-item
label="Your string: "
label-placement="left"
>
<n-input
v-model:value="compareString"
placeholder="Your string to compare..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
/>
</n-form-item>
<n-form-item
label="Your hash: "
label-placement="left"
>
<n-input
v-model:value="compareHash"
placeholder="Your hahs to compare..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
/>
</n-form-item>
<n-form-item
label="Do they match ? "
label-placement="left"
:show-feedback="false"
>
<div
class="compare-result"
:class="{positive:compareMatch}"
>
{{ compareMatch ? 'Yes' : 'No' }}
</div>
</n-form-item>
</n-form>
</n-card>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import {hashSync, compareSync} from 'bcryptjs'
import { useCopy } from '@/composable/copy';
import { useThemeVars } from 'naive-ui';
const themeVars = useThemeVars()
const input = ref('')
const saltCount = ref(10)
const hashed = computed(() => hashSync(input.value, saltCount.value))
const {copy} = useCopy({source: hashed, text:'Hashed string copied to the clipboard'})
const compareString = ref('')
const compareHash = ref('')
const compareMatch = computed(() => compareSync(compareString.value, compareHash.value))
</script>
<style lang="less" scoped>
.compare-result {
color: v-bind('themeVars.errorColor');
&.positive {
color: v-bind('themeVars.successColor')
}
}
</style>

11
src/tools/bcrypt/index.ts Normal file
View File

@@ -0,0 +1,11 @@
import { LockSquare } from '@vicons/tabler';
import type { ITool } from './../Tool';
export const tool: ITool = {
name: 'Bcrypt',
path: '/bcrypt',
description: 'Hash and compare text string using bcrypt. Bcrypt is a password-hashing function based on the Blowfish cipher.',
keywords: ['bcrypt', 'hash', 'compare', 'password', 'salt', 'round', 'storage', 'crypto'],
component: () => import('./bcrypt.vue'),
icon: LockSquare,
};

View File

@@ -0,0 +1,114 @@
<template>
<n-card
v-for="{name, information} in sections"
:key="name"
:title="name"
style="margin-bottom: 15px;"
>
<n-grid
cols="1 400:2"
x-gap="12"
y-gap="12"
>
<n-gi
v-for="{label, value} in information"
:key="label"
class="information"
>
<n-card
:bordered="false"
embedded
>
<div class="label">
{{ label }}
</div>
<div class="value">
<n-ellipsis>
{{ value.value }}
</n-ellipsis>
</div>
</n-card>
</n-gi>
</n-grid>
</n-card>
</template>
<script setup lang="ts">
import { useWindowSize } from '@vueuse/core'
import { computed } from 'vue';
const { width, height } = useWindowSize()
const sections = [
{
name: 'Screen',
information: [
{
label: 'Screen size',
value: computed(() => `${window.screen.availWidth} x ${window.screen.availHeight}`)
},
{
label: 'Orientation',
value: computed(() => window.screen.orientation.type)
},
{
label: 'Orientation angle',
value: computed(() => `${window.screen.orientation.angle}°`)
},
{
label: 'Color depth',
value: computed(() => `${window.screen.colorDepth} bits`)
},
{
label: 'Pixel ratio',
value: computed(() => `${window.devicePixelRatio} dppx`)
},
{
label: 'Window size',
value: computed(() => `${width.value} x ${height.value}`)
}
]
},
{
name: 'Device',
information: [
{
label: 'Browser vendor',
value: computed(() => navigator.vendor)
},
{
label: 'Languages',
value: computed(() => navigator.languages.join(', '))
},
{
label: 'Plateform',
value: computed(() => navigator.platform)
},
{
label: 'User agent',
value: computed(() => navigator.userAgent)
}
]
}
]
</script>
<style lang="less" scoped>
.information {
.label {
font-size: 14px;
opacity: 0.8;
line-height: 1;
margin-bottom: 5px;
}
.value {
font-size: 20px;
font-weight: 400;
line-height: 1;
}
}
</style>

View File

@@ -0,0 +1,11 @@
import { DeviceDesktop } from '@vicons/tabler';
import type { ITool } from './../Tool';
export const tool: ITool = {
name: 'Device information',
path: '/device-information',
description: 'Get information about your current device (screen size, pixel-ratio, user agent, ...)',
keywords: ['device', 'information', 'screen', 'pixel', 'ratio', 'status', 'data', 'computer', 'size', 'user', 'agent'],
component: () => import('./device-information.vue'),
icon: DeviceDesktop,
};

View File

@@ -1,6 +1,9 @@
import { LockOpen } from '@vicons/tabler';
import type { ToolCategory } from './Tool';
import { tool as urlParser } from './url-parser';
import { tool as deviceInformation } from './device-information';
import { tool as bcrypt } from './bcrypt';
import { tool as caseConverter } from './case-converter';
import { tool as colorConverter } from './color-converter';
import { tool as qrCodeGenerator } from './qr-code-generator';
@@ -24,7 +27,7 @@ export const toolsByCategory: ToolCategory[] = [
{
name: 'Crypto',
icon: LockOpen,
components: [tokenGenerator, hashText, uuidGenerator, cypher, bip39],
components: [tokenGenerator, hashText, bcrypt, uuidGenerator, cypher, bip39],
},
{
name: 'Converter',
@@ -34,7 +37,7 @@ export const toolsByCategory: ToolCategory[] = [
{
name: 'Web',
icon: LockOpen,
components: [urlEncoder, qrCodeGenerator],
components: [urlEncoder, qrCodeGenerator, urlParser, deviceInformation],
},
{
name: 'Development',

View File

@@ -0,0 +1,11 @@
import { Unlink } from '@vicons/tabler';
import type { ITool } from './../Tool';
export const tool: ITool = {
name: 'Url parser',
path: '/url-parser',
description: 'Parse an url string to get all the differents parts (protocol, origin, params, port, username-password, ...)',
keywords: ['url', 'parser', 'protocol', 'origin', 'params', 'port', 'username', 'password', 'href'],
component: () => import('./url-parser.vue'),
icon: Unlink,
};

View File

@@ -0,0 +1,118 @@
<template>
<n-card>
<n-form-item
label="Your url to parse:"
:feedback="validation.message"
:validation-status="validation.status"
>
<n-input
v-model:value="urlToParse"
placeholder="Your url to parse..."
/>
</n-form-item>
<n-divider style="margin-top: 0;" />
<n-form>
<n-input-group
v-for="{title, key} in properties"
:key="key"
>
<n-input-group-label
style="flex: 0 0 120px;"
>
{{ title }}:
</n-input-group-label>
<input-copyable
:value="(urlParsed?.[key] as string) ?? ''"
readonly
placeholder=" "
/>
</n-input-group>
<n-input-group
v-for="[k, v] in Object.entries(Object.fromEntries(urlParsed?.searchParams.entries() ?? []))"
:key="k"
>
<n-input-group-label
style="flex: 0 0 120px;"
>
<n-icon :component="SubdirectoryArrowRightRound" />
</n-input-group-label>
<input-copyable
:value="k"
readonly
/>
<input-copyable
:value="v"
readonly
/>
</n-input-group>
</n-form>
</n-card>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import { SubdirectoryArrowRightRound } from '@vicons/material';
import InputCopyable from '../../components/InputCopyable.vue';
import { useValidation } from '@/composable/validation';
const urlToParse = ref('https://me:pwd@it-tools.tech:3000/url-parser?key1=value&key2=value2#the-hash')
const urlParsed = computed<URL | undefined>(() => {
try {
return new URL(urlToParse.value)
} catch (_) {
return undefined
}
})
const validation = useValidation({source: urlToParse, rules: [
{validator: (value) => {
try {
new URL(value)
return true;
} catch (_) {
return false
}
}, message: 'Invalid url'}
]})
const properties: {title: string, key: keyof URL}[] = [
{title: 'Protocol', key: 'protocol'},
{title: 'Username', key: 'username'},
{title: 'Password', key: 'password'},
{title: 'Hostname', key: 'hostname'},
{title: 'Port', key: 'port'},
{title: 'Path', key: 'pathname'},
{title: 'Params', key: 'search'},
]
</script>
<style lang="less" scoped>
.n-input-group-label {
text-align: right;
}
.n-input-group {
&:not(:first-child) > * {
::v-deep(.n-input__border), ::v-deep(.n-input-group-label__border) {
border-radius: 0;
border-top: none;
}
}
&:first-child > * {
::v-deep(.n-input__border), ::v-deep(.n-input-group-label__border) {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
}
</style>