Skip to content

Commit c95ac78

Browse files
authored
Merge pull request #257 from sunnydanu/feat(new-tool)--argon2-password-hashing-and-verification
feat(new-tool):-argon2-password-hashing-and-verification
2 parents fee025b + d3c850d commit c95ac78

File tree

8 files changed

+232
-43
lines changed

8 files changed

+232
-43
lines changed

components.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ declare module '@vue/runtime-core' {
1212
'404.page': typeof import('./src/pages/404.page.vue')['default']
1313
About: typeof import('./src/pages/About.vue')['default']
1414
App: typeof import('./src/App.vue')['default']
15+
Argon2HashGenerator: typeof import('./src/tools/argon2-hash-generator/argon2-hash-generator.vue')['default']
1516
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
1617
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
1718
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
@@ -148,6 +149,7 @@ declare module '@vue/runtime-core' {
148149
NAlert: typeof import('naive-ui')['NAlert']
149150
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
150151
NButton: typeof import('naive-ui')['NButton']
152+
NCard: typeof import('naive-ui')['NCard']
151153
NCheckbox: typeof import('naive-ui')['NCheckbox']
152154
NCode: typeof import('naive-ui')['NCode']
153155
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
@@ -164,6 +166,7 @@ declare module '@vue/runtime-core' {
164166
NH3: typeof import('naive-ui')['NH3']
165167
NIcon: typeof import('naive-ui')['NIcon']
166168
NImage: typeof import('naive-ui')['NImage']
169+
NInput: typeof import('naive-ui')['NInput']
167170
NInputNumber: typeof import('naive-ui')['NInputNumber']
168171
NLayout: typeof import('naive-ui')['NLayout']
169172
NLayoutSider: typeof import('naive-ui')['NLayoutSider']

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"figlet": "^1.7.0",
6767
"figue": "^1.2.0",
6868
"fuse.js": "^6.6.2",
69+
"hash-wasm": "^4.9.0",
6970
"highlight.js": "^11.7.0",
7071
"iarna-toml-esm": "^3.0.5",
7172
"ibantools": "^4.3.3",

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { expect, test } from '@playwright/test';
2+
3+
test.describe('Tool - Argon2 hash generator', () => {
4+
test.beforeEach(async ({ page }) => {
5+
await page.goto('/argon2-hash-generator');
6+
});
7+
8+
test('Has correct title', async ({ page }) => {
9+
await expect(page).toHaveTitle('GoDev.Run - Argon2 hash generator');
10+
});
11+
12+
test('hash a string a verify that the result match', async ({ page }) => {
13+
await page.getByTestId('input').fill('azerty');
14+
15+
await new Promise(resolve => setTimeout(resolve, 500));
16+
const hash = await page.getByTestId('hash').inputValue();
17+
18+
await page.getByTestId('compare-string').fill('azerty');
19+
await page.getByTestId('compare-hash').fill(hash);
20+
21+
await new Promise(resolve => setTimeout(resolve, 500));
22+
const doTheyMatch = await page.getByTestId('do-they-match').innerText();
23+
24+
expect(doTheyMatch.trim()).toEqual('Yes');
25+
});
26+
27+
test('hash a string a verify that the does not result match another string', async ({ page }) => {
28+
await page.getByTestId('input').fill('azerty');
29+
const hash = await page.getByTestId('hash').inputValue();
30+
31+
await page.getByTestId('compare-string').fill('NOT AZERTY');
32+
await page.getByTestId('compare-hash').fill(hash);
33+
const doTheyMatch = await page.getByTestId('do-they-match').innerText();
34+
35+
expect(doTheyMatch.trim()).toEqual('No');
36+
});
37+
});
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<script setup lang="ts">
2+
import { argon2Verify, argon2id } from 'hash-wasm';
3+
import { useCopy } from '@/composable/copy';
4+
5+
const input = ref('');
6+
const iterations = ref(32);
7+
const memorySize = ref(512);
8+
const hashLength = ref(32);
9+
10+
const hashed = computedAsync(
11+
async () =>
12+
argon2id({
13+
password: input.value,
14+
salt: window.crypto.getRandomValues(new Uint8Array(16)),
15+
parallelism: 1,
16+
iterations: iterations.value,
17+
memorySize: memorySize.value,
18+
hashLength: hashLength.value,
19+
outputType: 'encoded',
20+
}),
21+
'',
22+
);
23+
const { copy } = useCopy({ source: hashed, text: 'Hashed string copied to the clipboard' });
24+
25+
const compareString = ref('');
26+
const compareHash = ref('');
27+
const compareMatch = computedAsync(
28+
() => argon2Verify({ password: compareString.value, hash: compareHash.value }),
29+
false,
30+
);
31+
</script>
32+
33+
<template>
34+
<n-card title="Hash">
35+
<n-form label-width="120">
36+
<n-form-item label="Your string: " label-placement="left">
37+
<n-input
38+
v-model:value="input"
39+
placeholder="Your string to bcrypt..."
40+
autocomplete="off"
41+
autocorrect="off"
42+
autocapitalize="off"
43+
spellcheck="false"
44+
:input-props="{
45+
'data-test-id': 'input',
46+
}"
47+
/>
48+
</n-form-item>
49+
<n-form-item label="Iteration: " label-placement="left">
50+
<n-input-number v-model:value="iterations" placeholder="Iterations..." min="0" w-full />
51+
</n-form-item>
52+
<n-form-item label="Memory size: " label-placement="left">
53+
<n-input-number v-model:value="memorySize" placeholder="Memory size..." min="0" w-full />
54+
</n-form-item>
55+
<n-input
56+
:value="hashed"
57+
readonly
58+
style="text-align: center"
59+
placeholder="Set a string to hash above..."
60+
:input-props="{
61+
'data-test-id': 'hash',
62+
}"
63+
/>
64+
</n-form>
65+
<br>
66+
<n-space justify="center">
67+
<n-button secondary @click="copy">
68+
Copy hash
69+
</n-button>
70+
</n-space>
71+
</n-card>
72+
73+
<n-card title="Compare string with hash">
74+
<n-form label-width="120">
75+
<n-form-item label="Your string: " label-placement="left">
76+
<n-input
77+
v-model:value="compareString"
78+
placeholder="Your string to compare..."
79+
autocomplete="off"
80+
autocorrect="off"
81+
autocapitalize="off"
82+
spellcheck="false"
83+
:input-props="{
84+
'data-test-id': 'compare-string',
85+
}"
86+
/>
87+
</n-form-item>
88+
<n-form-item label="Your hash: " label-placement="left">
89+
<n-input
90+
v-model:value="compareHash"
91+
placeholder="Your hash to compare..."
92+
autocomplete="off"
93+
autocorrect="off"
94+
autocapitalize="off"
95+
spellcheck="false"
96+
:input-props="{
97+
'data-test-id': 'compare-hash',
98+
}"
99+
/>
100+
</n-form-item>
101+
<n-form-item label="Do they match ? " label-placement="left" :show-feedback="false">
102+
<span data-test-id="do-they-match">
103+
<n-tag v-if="compareMatch" :bordered="false" type="success" round>Yes</n-tag>
104+
<n-tag v-else :bordered="false" type="error" round>No</n-tag>
105+
</span>
106+
</n-form-item>
107+
</n-form>
108+
</n-card>
109+
</template>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Lock } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'Argon2 hash generator',
6+
path: '/argon2-hash-generator',
7+
description: 'Hash and compare string (password) using Argon2',
8+
keywords: ['argon2', 'hash', 'generator', 'password', 'salt', 'crypto', 'security'],
9+
component: () => import('./argon2-hash-generator.vue'),
10+
icon: Lock,
11+
createdAt: new Date('2023-04-16'),
12+
});

src/tools/bcrypt/bcrypt.vue

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
<script setup lang="ts">
22
import { compareSync, hashSync } from 'bcryptjs';
3-
import { useThemeVars } from 'naive-ui';
43
import { useCopy } from '@/composable/copy';
54
6-
const themeVars = useThemeVars();
7-
85
const input = ref('');
96
const saltCount = ref(10);
107
const hashed = computed(() => hashSync(input.value, saltCount.value));
@@ -16,53 +13,61 @@ const compareMatch = computed(() => compareSync(compareString.value, compareHash
1613
</script>
1714

1815
<template>
19-
<c-card title="Hash">
20-
<c-input-text
21-
v-model:value="input"
22-
placeholder="Your string to bcrypt..."
23-
raw-text
24-
label="Your string: "
25-
label-position="left"
26-
label-align="right"
27-
label-width="120px"
28-
mb-2
29-
/>
30-
<n-form-item label="Salt count: " label-placement="left" label-width="120">
31-
<n-input-number v-model:value="saltCount" placeholder="Salt rounds..." :max="100" :min="0" w-full />
32-
</n-form-item>
33-
34-
<c-input-text :value="hashed" readonly text-center />
35-
36-
<div mt-5 flex justify-center>
37-
<c-button @click="copy()">
16+
<n-card title="Hash">
17+
<n-form label-width="120">
18+
<n-form-item label="Your string: " label-placement="left">
19+
<n-input
20+
v-model:value="input"
21+
placeholder="Your string to bcrypt..."
22+
autocomplete="off"
23+
autocorrect="off"
24+
autocapitalize="off"
25+
spellcheck="false"
26+
/>
27+
</n-form-item>
28+
<n-form-item label="Salt count: " label-placement="left">
29+
<n-input-number v-model:value="saltCount" placeholder="Salt rounds..." :max="10" :min="0" w-full />
30+
</n-form-item>
31+
<n-input :value="hashed" readonly style="text-align: center" />
32+
</n-form>
33+
<br>
34+
<n-space justify="center">
35+
<n-button secondary @click="copy">
3836
Copy hash
39-
</c-button>
40-
</div>
41-
</c-card>
37+
</n-button>
38+
</n-space>
39+
</n-card>
4240

43-
<c-card title="Compare string with hash">
41+
<n-card title="Compare string with hash">
4442
<n-form label-width="120">
4543
<n-form-item label="Your string: " label-placement="left">
46-
<c-input-text v-model:value="compareString" placeholder="Your string to compare..." raw-text />
44+
<n-input
45+
v-model:value="compareString"
46+
placeholder="Your string to compare..."
47+
autocomplete="off"
48+
autocorrect="off"
49+
autocapitalize="off"
50+
spellcheck="false"
51+
/>
4752
</n-form-item>
4853
<n-form-item label="Your hash: " label-placement="left">
49-
<c-input-text v-model:value="compareHash" placeholder="Your hash to compare..." raw-text />
54+
<n-input
55+
v-model:value="compareHash"
56+
placeholder="Your hash to compare..."
57+
autocomplete="off"
58+
autocorrect="off"
59+
autocapitalize="off"
60+
spellcheck="false"
61+
/>
5062
</n-form-item>
5163
<n-form-item label="Do they match ? " label-placement="left" :show-feedback="false">
52-
<div class="compare-result" :class="{ positive: compareMatch }">
53-
{{ compareMatch ? 'Yes' : 'No' }}
54-
</div>
64+
<n-tag v-if="compareMatch" :bordered="false" type="success" round>
65+
Yes
66+
</n-tag>
67+
<n-tag v-else :bordered="false" type="error" round>
68+
No
69+
</n-tag>
5570
</n-form-item>
5671
</n-form>
57-
</c-card>
72+
</n-card>
5873
</template>
59-
60-
<style lang="less" scoped>
61-
.compare-result {
62-
color: v-bind('themeVars.errorColor');
63-
64-
&.positive {
65-
color: v-bind('themeVars.successColor');
66-
}
67-
}
68-
</style>

src/tools/index.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { tool as base64FileConverter } from './base64-file-converter';
22
import { tool as base64StringConverter } from './base64-string-converter';
33
import { tool as basicAuthGenerator } from './basic-auth-generator';
4+
import { tool as argon2HashGenerator } from './argon2-hash-generator';
45
import { tool as imageResizer } from './image-resizer';
56
import { tool as dnsQueries } from './dns-queries';
67
import { tool as jsonEditor } from './json-editor';
@@ -95,7 +96,20 @@ import { tool as yamlViewer } from './yaml-viewer';
9596
export const toolsByCategory: ToolCategory[] = [
9697
{
9798
name: 'Crypto',
98-
components: [tokenGenerator, hashText, bcrypt, uuidGenerator, ulidGenerator, cypher, bip39, hmacGenerator, rsaKeyPairGenerator, passwordStrengthAnalyser, pdfSignatureChecker],
99+
components: [
100+
tokenGenerator,
101+
hashText,
102+
bcrypt,
103+
argon2HashGenerator,
104+
uuidGenerator,
105+
ulidGenerator,
106+
cypher,
107+
bip39,
108+
hmacGenerator,
109+
rsaKeyPairGenerator,
110+
passwordStrengthAnalyser,
111+
pdfSignatureChecker,
112+
],
99113
},
100114
{
101115
name: 'Converter',

0 commit comments

Comments
 (0)