mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-14 19:22:14 +01:00
add linter, prettier and typescript support for jetstream (#1)
* add linter, prettier and typescript support for jetstream * add github actions for lint, build and typecheck * add composer install to build action * fix composer lock * add ext-intl and fixed php version * fix intl php extension install * add tip php extension to github npm build action * fix php version to 8.3.1 * change github php base action * fix primary button default type * updated typescript types from Team to Organization --------- Co-authored-by: Gregor Vostrak <gregorvostrak@Gregors-MacBook-Pro.local>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { router, useForm, usePage } from '@inertiajs/vue3';
|
||||
import ActionSection from '@/Components/ActionSection.vue';
|
||||
@@ -9,12 +9,18 @@ import InputLabel from '@/Components/InputLabel.vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import axios from 'axios';
|
||||
import type { JetstreamUser } from '@/types/jetstream';
|
||||
|
||||
const props = defineProps({
|
||||
requiresConfirmation: Boolean,
|
||||
});
|
||||
const props = defineProps<{
|
||||
requiresConfirmation: boolean;
|
||||
}>();
|
||||
|
||||
const page = usePage();
|
||||
const page = usePage<{
|
||||
auth: {
|
||||
user: JetstreamUser;
|
||||
};
|
||||
}>();
|
||||
const enabling = ref(false);
|
||||
const confirming = ref(false);
|
||||
const disabling = ref(false);
|
||||
@@ -27,11 +33,11 @@ const confirmationForm = useForm({
|
||||
});
|
||||
|
||||
const twoFactorEnabled = computed(
|
||||
() => ! enabling.value && page.props.auth.user?.two_factor_enabled,
|
||||
() => !enabling.value && page.props.auth.user?.two_factor_enabled
|
||||
);
|
||||
|
||||
watch(twoFactorEnabled, () => {
|
||||
if (! twoFactorEnabled.value) {
|
||||
if (!twoFactorEnabled.value) {
|
||||
confirmationForm.reset();
|
||||
confirmationForm.clearErrors();
|
||||
}
|
||||
@@ -40,41 +46,46 @@ watch(twoFactorEnabled, () => {
|
||||
const enableTwoFactorAuthentication = () => {
|
||||
enabling.value = true;
|
||||
|
||||
router.post(route('two-factor.enable'), {}, {
|
||||
preserveScroll: true,
|
||||
onSuccess: () => Promise.all([
|
||||
showQrCode(),
|
||||
showSetupKey(),
|
||||
showRecoveryCodes(),
|
||||
]),
|
||||
onFinish: () => {
|
||||
enabling.value = false;
|
||||
confirming.value = props.requiresConfirmation;
|
||||
},
|
||||
});
|
||||
router.post(
|
||||
route('two-factor.enable'),
|
||||
{},
|
||||
{
|
||||
preserveScroll: true,
|
||||
onSuccess: () =>
|
||||
Promise.all([
|
||||
showQrCode(),
|
||||
showSetupKey(),
|
||||
showRecoveryCodes(),
|
||||
]),
|
||||
onFinish: () => {
|
||||
enabling.value = false;
|
||||
confirming.value = props.requiresConfirmation;
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const showQrCode = () => {
|
||||
return axios.get(route('two-factor.qr-code')).then(response => {
|
||||
return axios.get(route('two-factor.qr-code')).then((response) => {
|
||||
qrCode.value = response.data.svg;
|
||||
});
|
||||
};
|
||||
|
||||
const showSetupKey = () => {
|
||||
return axios.get(route('two-factor.secret-key')).then(response => {
|
||||
return axios.get(route('two-factor.secret-key')).then((response) => {
|
||||
setupKey.value = response.data.secretKey;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const showRecoveryCodes = () => {
|
||||
return axios.get(route('two-factor.recovery-codes')).then(response => {
|
||||
return axios.get(route('two-factor.recovery-codes')).then((response) => {
|
||||
recoveryCodes.value = response.data;
|
||||
});
|
||||
};
|
||||
|
||||
const confirmTwoFactorAuthentication = () => {
|
||||
confirmationForm.post(route('two-factor.confirm'), {
|
||||
errorBag: "confirmTwoFactorAuthentication",
|
||||
errorBag: 'confirmTwoFactorAuthentication',
|
||||
preserveScroll: true,
|
||||
preserveState: true,
|
||||
onSuccess: () => {
|
||||
@@ -106,48 +117,66 @@ const disableTwoFactorAuthentication = () => {
|
||||
|
||||
<template>
|
||||
<ActionSection>
|
||||
<template #title>
|
||||
Two Factor Authentication
|
||||
</template>
|
||||
<template #title> Two Factor Authentication </template>
|
||||
|
||||
<template #description>
|
||||
Add additional security to your account using two factor authentication.
|
||||
Add additional security to your account using two factor
|
||||
authentication.
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<h3 v-if="twoFactorEnabled && ! confirming" class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
<h3
|
||||
v-if="twoFactorEnabled && !confirming"
|
||||
class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
You have enabled two factor authentication.
|
||||
</h3>
|
||||
|
||||
<h3 v-else-if="twoFactorEnabled && confirming" class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
<h3
|
||||
v-else-if="twoFactorEnabled && confirming"
|
||||
class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
Finish enabling two factor authentication.
|
||||
</h3>
|
||||
|
||||
<h3 v-else class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
<h3
|
||||
v-else
|
||||
class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||
You have not enabled two factor authentication.
|
||||
</h3>
|
||||
|
||||
<div class="mt-3 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||||
<p>
|
||||
When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone's Google Authenticator application.
|
||||
When two factor authentication is enabled, you will be
|
||||
prompted for a secure, random token during authentication.
|
||||
You may retrieve this token from your phone's Google
|
||||
Authenticator application.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="twoFactorEnabled">
|
||||
<div v-if="qrCode">
|
||||
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||||
<div
|
||||
class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||||
<p v-if="confirming" class="font-semibold">
|
||||
To finish enabling two factor authentication, scan the following QR code using your phone's authenticator application or enter the setup key and provide the generated OTP code.
|
||||
To finish enabling two factor authentication, scan
|
||||
the following QR code using your phone's
|
||||
authenticator application or enter the setup key and
|
||||
provide the generated OTP code.
|
||||
</p>
|
||||
|
||||
<p v-else>
|
||||
Two factor authentication is now enabled. Scan the following QR code using your phone's authenticator application or enter the setup key.
|
||||
Two factor authentication is now enabled. Scan the
|
||||
following QR code using your phone's authenticator
|
||||
application or enter the setup key.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 p-2 inline-block bg-white" v-html="qrCode" />
|
||||
<div
|
||||
class="mt-4 p-2 inline-block bg-white"
|
||||
v-html="qrCode" />
|
||||
|
||||
<div v-if="setupKey" class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||||
<div
|
||||
v-if="setupKey"
|
||||
class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||||
<p class="font-semibold">
|
||||
Setup Key: <span v-html="setupKey"></span>
|
||||
</p>
|
||||
@@ -165,21 +194,27 @@ const disableTwoFactorAuthentication = () => {
|
||||
inputmode="numeric"
|
||||
autofocus
|
||||
autocomplete="one-time-code"
|
||||
@keyup.enter="confirmTwoFactorAuthentication"
|
||||
/>
|
||||
@keyup.enter="confirmTwoFactorAuthentication" />
|
||||
|
||||
<InputError :message="confirmationForm.errors.code" class="mt-2" />
|
||||
<InputError
|
||||
:message="confirmationForm.errors.code"
|
||||
class="mt-2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="recoveryCodes.length > 0 && ! confirming">
|
||||
<div class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||||
<div v-if="recoveryCodes.length > 0 && !confirming">
|
||||
<div
|
||||
class="mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||||
<p class="font-semibold">
|
||||
Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.
|
||||
Store these recovery codes in a secure password
|
||||
manager. They can be used to recover access to your
|
||||
account if your two factor authentication device is
|
||||
lost.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-1 max-w-xl mt-4 px-4 py-4 font-mono text-sm bg-gray-100 dark:bg-gray-900 dark:text-gray-100 rounded-lg">
|
||||
<div
|
||||
class="grid gap-1 max-w-xl mt-4 px-4 py-4 font-mono text-sm bg-gray-100 dark:bg-gray-900 dark:text-gray-100 rounded-lg">
|
||||
<div v-for="code in recoveryCodes" :key="code">
|
||||
{{ code }}
|
||||
</div>
|
||||
@@ -188,61 +223,63 @@ const disableTwoFactorAuthentication = () => {
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<div v-if="! twoFactorEnabled">
|
||||
<ConfirmsPassword @confirmed="enableTwoFactorAuthentication">
|
||||
<PrimaryButton type="button" :class="{ 'opacity-25': enabling }" :disabled="enabling">
|
||||
<div v-if="!twoFactorEnabled">
|
||||
<ConfirmsPassword
|
||||
@confirmed="enableTwoFactorAuthentication">
|
||||
<PrimaryButton
|
||||
type="button"
|
||||
:class="{ 'opacity-25': enabling }"
|
||||
:disabled="enabling">
|
||||
Enable
|
||||
</PrimaryButton>
|
||||
</ConfirmsPassword>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<ConfirmsPassword @confirmed="confirmTwoFactorAuthentication">
|
||||
<ConfirmsPassword
|
||||
@confirmed="confirmTwoFactorAuthentication">
|
||||
<PrimaryButton
|
||||
v-if="confirming"
|
||||
type="button"
|
||||
class="me-3"
|
||||
:class="{ 'opacity-25': enabling }"
|
||||
:disabled="enabling"
|
||||
>
|
||||
:disabled="enabling">
|
||||
Confirm
|
||||
</PrimaryButton>
|
||||
</ConfirmsPassword>
|
||||
|
||||
<ConfirmsPassword @confirmed="regenerateRecoveryCodes">
|
||||
<SecondaryButton
|
||||
v-if="recoveryCodes.length > 0 && ! confirming"
|
||||
class="me-3"
|
||||
>
|
||||
v-if="recoveryCodes.length > 0 && !confirming"
|
||||
class="me-3">
|
||||
Regenerate Recovery Codes
|
||||
</SecondaryButton>
|
||||
</ConfirmsPassword>
|
||||
|
||||
<ConfirmsPassword @confirmed="showRecoveryCodes">
|
||||
<SecondaryButton
|
||||
v-if="recoveryCodes.length === 0 && ! confirming"
|
||||
class="me-3"
|
||||
>
|
||||
v-if="recoveryCodes.length === 0 && !confirming"
|
||||
class="me-3">
|
||||
Show Recovery Codes
|
||||
</SecondaryButton>
|
||||
</ConfirmsPassword>
|
||||
|
||||
<ConfirmsPassword @confirmed="disableTwoFactorAuthentication">
|
||||
<ConfirmsPassword
|
||||
@confirmed="disableTwoFactorAuthentication">
|
||||
<SecondaryButton
|
||||
v-if="confirming"
|
||||
:class="{ 'opacity-25': disabling }"
|
||||
:disabled="disabling"
|
||||
>
|
||||
:disabled="disabling">
|
||||
Cancel
|
||||
</SecondaryButton>
|
||||
</ConfirmsPassword>
|
||||
|
||||
<ConfirmsPassword @confirmed="disableTwoFactorAuthentication">
|
||||
<ConfirmsPassword
|
||||
@confirmed="disableTwoFactorAuthentication">
|
||||
<DangerButton
|
||||
v-if="! confirming"
|
||||
v-if="!confirming"
|
||||
:class="{ 'opacity-25': disabling }"
|
||||
:disabled="disabling"
|
||||
>
|
||||
:disabled="disabling">
|
||||
Disable
|
||||
</DangerButton>
|
||||
</ConfirmsPassword>
|
||||
|
||||
Reference in New Issue
Block a user