Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Refactored App.vue #166

Merged
merged 34 commits into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
301fb75
extracted bottom navigation in own component
May 11, 2023
200c332
removed old code from app.vue
May 11, 2023
976477c
extracted SettingsPrompt from Navigation component
May 11, 2023
56f648f
removed unsude code form Navigation component
May 11, 2023
8e57360
extracted Notificantion from App
May 11, 2023
0f678ca
removed unused code etc.
May 11, 2023
28d794b
removed unused css
May 11, 2023
c91f38b
reorganisation of composables
May 11, 2023
123b4e7
reorganization of the notification component
May 11, 2023
8b360fe
adjusted css styling
May 11, 2023
41b9eb6
Better renaming
May 11, 2023
30086d1
additional notification
May 11, 2023
1a6d348
renaming
May 11, 2023
ba242ad
extracted functions into composables
May 11, 2023
4f56c47
possible fix: crypto is not defined ?
May 11, 2023
b46fb88
used old generation fo token
May 12, 2023
d332d2a
revert to working ci
May 12, 2023
30f9e7d
test for ci error
May 12, 2023
e28bcc7
useTokenGenerator composable
May 12, 2023
59b3e21
removed unused code
May 12, 2023
a0bbdd0
test for token generator
May 12, 2023
46ed385
testing token package
May 12, 2023
3d3508a
replacing
May 12, 2023
3b59468
rework for useClipboard and simple test
May 12, 2023
255cc69
reimplementing token generation
May 12, 2023
024d97b
removing unused core etc.
May 12, 2023
43c559e
removed settings
May 12, 2023
3199850
show error after closing and repoening
May 12, 2023
b678cbb
resolving issues
May 12, 2023
2f9b15e
resolved clipboard composabled and tests
May 12, 2023
88d7562
renaming
May 12, 2023
87f60f8
clipboard not supported workaround
May 14, 2023
2509d2a
fix rule validation
May 15, 2023
090c77a
fixed false token generation etc.
May 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 44 additions & 27 deletions src/components/SettingsPrompt/SettingsPrompt.vue
BeierKevin marked this conversation as resolved.
Show resolved Hide resolved
BeierKevin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,9 @@
: 'mdi-eye-off-outline'
"
:type="tokenVisibility ? 'text' : 'password'"
:rules="[
rules.uppercase,
rules.lowercase,
rules.min,
rules.required,
rules.special,
rules.number,
]"
:error="!validateAccessToken()"
:error-messages="errorMessage"
@click:append-inner="toggleTokenVisibility()"
@update:model-value="validateAccessToken()"
persistent-placeholder
>
<template v-slot:append>
Expand All @@ -89,7 +80,6 @@
"
></v-icon>
</template>

Copy to clipboard
</v-tooltip>
</template>
Expand All @@ -102,7 +92,6 @@
@click="regenerateAccessToken"
></v-icon>
</template>

Generate new token
</v-tooltip>
</template>
Expand Down Expand Up @@ -160,11 +149,12 @@ import { Ref, ref, watch } from 'vue';
* Composables
*/
const { writeClipboardText } = useClipboard();
const { rules, generateValidToken } = useTokenGenerator();
const { defaultRules, generateValidToken } = useTokenGenerator();

/**
* Data
*/
const accessToken = ref('');
const isAccessTokenValid = ref(false);
const errorMessage: Ref<string[]> = ref([]);
const tokenVisibility = ref(false);
Expand All @@ -176,31 +166,42 @@ const streamRegexAndCaptureAreaSettings = ref(false);
* Dialog visibility
*/
const dialog = ref(false);

watch(
() => dialog.value,
(value) => {
if (value) {
// generate token if empty
if (accessToken.value === '') regenerateAccessToken();
if (accessToken.value === '') {
regenerateAccessToken();
return;
} else {
// try to validate token if not empty
errorMessage.value = Object.values(defaultRules)
.map((rule) => rule(accessToken.value))
.filter((value) => typeof value === 'string') as string[];
}
} else {
// reset validation state
const isValid = Object.values(rules).every(
const isValid = Object.values(defaultRules).every(
(rule) => rule(accessToken.value) === true
);

if (isAccessTokenValid.value === isValid) {
errorMessage.value = Object.values(rules)
errorMessage.value = Object.values(defaultRules)
.map((rule) => rule(accessToken.value))
.filter((value) => typeof value === 'string') as string[];
}
}
}
);

/**
* Access token
*/
const accessToken = ref('');
watch(
() => accessToken.value,
(value) => {
validate();
}
);

/**
* Start the session
Expand Down Expand Up @@ -242,30 +243,46 @@ async function regenerateAccessToken() {
/**
* Function which will validate the access token and notifies the user
*/
function validateAccessToken() {
const isValid = Object.values(rules).every(
function validate() {
const isValid = Object.values(defaultRules).every(
(rule) => rule(accessToken.value) === true
);

if (isAccessTokenValid.value === isValid) {
return isValid;
}

isAccessTokenValid.value = isValid;

errorMessage.value = Object.values(defaultRules)
.map((rule) => rule(accessToken.value))
.filter((value) => typeof value === 'string') as string[];

if (!isValid && isSessionActive.value) {
stopSession();
useNotificationSystem().createErrorNotification({
title: 'Session stopped',
message: 'The access token is invalid',
});
} else if (isValid) {
} else if (isValid && errorMessage.value.length === 0) {
useNotificationSystem().createSuccessNotification({
title: 'The access token is valid',
});
}
}

return isValid;
/**
* Function which will validate the access token and returns a boolean
* @returns boolean
*/
function validateAccessToken() {
// check if the access token is valid via the defaultRules
const isValid = Object.values(defaultRules).every(
(rule) => rule(accessToken.value) === true
);

if (isAccessTokenValid.value === isValid) {
return true;
}

isAccessTokenValid.value = isValid;
return false;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/composables/useClipboard/useClipboard.test.ts
BeierKevin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ describe('useClipboard Composable', () => {
const text = 'Hello, world!';
const result = await writeClipboardText(text);

/**
* It is currently not possible to write into the clipboard when run in a GitHub Action therefore always true
*/
if (result) {
expect(result).toBe(true);
expect(clipboardText.value).toBe(text);
Expand All @@ -35,6 +38,9 @@ describe('useClipboard Composable', () => {

const result = await readClipboardText();

/**
* It is currently not possible to read the clipboard when run in a GitHub Action therefore always true
*/
if (result) {
expect(result).toBe(text);
} else {
Expand Down
15 changes: 8 additions & 7 deletions src/composables/useTokenGenerator/useTokenGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { describe, it, expect } from 'vitest';
import useTokenGenerator from '@/composables/useTokenGenerator/useTokenGenerator';

describe('useTokenGenerator Composable', () => {
const { generateValidToken, rules, minTokenLenght } = useTokenGenerator();
const { generateValidToken, defaultRules, minTokenLenght } =
useTokenGenerator();

it('generateToken returns a string', () => {
const token = generateValidToken();
Expand All @@ -18,12 +19,12 @@ describe('useTokenGenerator Composable', () => {
const runs = 100;
for (let index = 0; index < runs; index++) {
const token = generateValidToken();
expect(rules.required(token)).toBe(true);
expect(rules.min(token)).toBe(true);
expect(rules.uppercase(token)).toBe(true);
expect(rules.lowercase(token)).toBe(true);
expect(rules.special(token)).toBe(true);
expect(rules.number(token)).toBe(true);
expect(defaultRules.required(token)).toBe(true);
expect(defaultRules.min(token)).toBe(true);
expect(defaultRules.uppercase(token)).toBe(true);
expect(defaultRules.lowercase(token)).toBe(true);
expect(defaultRules.special(token)).toBe(true);
expect(defaultRules.number(token)).toBe(true);
Claiyc marked this conversation as resolved.
Show resolved Hide resolved
}
});
});
43 changes: 13 additions & 30 deletions src/composables/useTokenGenerator/useTokenGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ export default function useTokenGenerator() {
const minTokenLenght = ref(8);

/**
* Rules for the access token
* Default Rules for the access token
*/
const rules = {
const defaultRules = {
required: (value: string) =>
!!value || 'An access token is required to start a session',
min: (v: string) =>
Expand All @@ -31,7 +31,7 @@ export default function useTokenGenerator() {
special: (v: string) =>
/[\W_]/.test(v) || 'Must include at least one special character',
number: (v: string) =>
/[0-9]*/.test(v) || 'Must include at least one number',
/[0-9]+/.test(v) || 'Must include at least one number',
};

/**
Expand Down Expand Up @@ -62,46 +62,29 @@ export default function useTokenGenerator() {
return generatedToken;
};

/**
* Generate multiple tokens using the generateToken function, but they are not guaranteed to be valid tokens (they may not meet the rules)
* @param count
* @returns
*/
const generateMultipleTokens = (count: number = 16): string[] => {
const tokens: string[] = [];
for (let i = 0; i < count; i++) {
const token = generateToken();
tokens.push(token);
}
return tokens;
};

/**
* Generate a valid token using the rules defined in the rules object
* @returns a valid token
*/
const generateValidToken = (): string => {
const tokens = generateMultipleTokens();
for (const token of tokens) {
if (
rules.lowercase(token) === true &&
rules.uppercase(token) === true &&
rules.special(token) === true &&
rules.number(token) === true &&
rules.min(token) === true
) {
return token;
}
const token = generateToken();
if (
defaultRules.lowercase(token) === true &&
defaultRules.uppercase(token) === true &&
defaultRules.special(token) === true &&
defaultRules.number(token) === true &&
defaultRules.min(token) === true
) {
return token;
}
return generateValidToken();
};

return {
characterSet,
minTokenLenght,
rules,
defaultRules,
generateToken,
generateMultipleTokens,
generateValidToken,
};
}