Add in registration token requirement to prevent unauthorised registrations.
This commit is contained in:
parent
5268d6aecd
commit
0d277e3035
4 changed files with 50 additions and 8 deletions
|
@ -9,6 +9,7 @@ import {
|
|||
import { isoBase64URL } from '@simplewebauthn/server/helpers'; // Ensure this is imported if not already
|
||||
import prisma from '../database.js';
|
||||
import { rpID, rpName, origin, challengeStore } from '../server.js'; // Import RP details and challenge store
|
||||
import { getSetting } from '../utils/settings.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
|
@ -49,13 +50,21 @@ async function getAuthenticatorByCredentialID(credentialID)
|
|||
router.post('/generate-registration-options', async(req, res) =>
|
||||
{
|
||||
// Destructure username, email, and fullName from the request body
|
||||
const { username, email, fullName } = req.body;
|
||||
const { username, email, fullName, registrationToken } = req.body;
|
||||
|
||||
if (!username)
|
||||
{
|
||||
return res.status(400).json({ error: 'Username is required' });
|
||||
}
|
||||
|
||||
//Check if the registrationToken matches the setting
|
||||
const registrationTokenSetting = await getSetting('REGISTRATION_TOKEN');
|
||||
|
||||
if (registrationTokenSetting !== registrationToken)
|
||||
{
|
||||
return res.status(403).json({ error: 'Invalid registration token' });
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
let user = await getUserByUsername(username);
|
||||
|
@ -71,7 +80,6 @@ router.post('/generate-registration-options', async(req, res) =>
|
|||
data: userData,
|
||||
});
|
||||
}
|
||||
// ... rest of the existing logic ...
|
||||
|
||||
const userAuthenticators = await getUserAuthenticators(user.id);
|
||||
|
||||
|
|
|
@ -35,6 +35,15 @@
|
|||
:rules="[val => !!val || 'Full Name is required']"
|
||||
@keyup.enter="handleRegister"
|
||||
/>
|
||||
<q-input
|
||||
v-model="registrationToken"
|
||||
label="Registration Token"
|
||||
outlined
|
||||
class="q-mb-md"
|
||||
:rules="[val => !!val || 'Registration Token is required']"
|
||||
:readonly="!showTokenInput"
|
||||
@keyup.enter="handleRegister"
|
||||
/>
|
||||
<q-btn
|
||||
label="Register Passkey"
|
||||
color="primary"
|
||||
|
@ -70,8 +79,8 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'; // Remove computed and onMounted
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ref, onMounted } from 'vue'; // Add onMounted
|
||||
import { useRouter, useRoute } from 'vue-router'; // Add useRoute
|
||||
import { startRegistration } from '@simplewebauthn/browser';
|
||||
import axios from 'boot/axios';
|
||||
// Remove auth store import
|
||||
|
@ -80,6 +89,7 @@ const loading = ref(false);
|
|||
const errorMessage = ref('');
|
||||
const successMessage = ref('');
|
||||
const router = useRouter();
|
||||
const route = useRoute(); // Get route object
|
||||
// Remove auth store usage
|
||||
|
||||
// Remove isLoggedIn computed property
|
||||
|
@ -87,13 +97,30 @@ const router = useRouter();
|
|||
const username = ref('');
|
||||
const email = ref('');
|
||||
const fullName = ref('');
|
||||
const registrationToken = ref(''); // Add registrationToken ref
|
||||
const showTokenInput = ref(false); // Control visibility of token input
|
||||
|
||||
// Check for token in route params when component mounts
|
||||
onMounted(() =>
|
||||
{
|
||||
const tokenFromRoute = route.params.token;
|
||||
if (tokenFromRoute && typeof tokenFromRoute === 'string')
|
||||
{
|
||||
registrationToken.value = tokenFromRoute;
|
||||
showTokenInput.value = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
showTokenInput.value = true; // Show input if no token in route
|
||||
}
|
||||
});
|
||||
|
||||
// Remove onMounted hook
|
||||
|
||||
async function handleRegister()
|
||||
{
|
||||
// Validate all fields
|
||||
if (!username.value || !email.value || !fullName.value)
|
||||
// Validate all fields including registration token if input is shown
|
||||
if (!username.value || !email.value || !fullName.value || (showTokenInput.value && !registrationToken.value))
|
||||
{
|
||||
errorMessage.value = 'Please fill in all required fields.';
|
||||
return;
|
||||
|
@ -111,11 +138,12 @@ async function handleRegister()
|
|||
|
||||
try
|
||||
{
|
||||
// Prepare payload - always include all fields
|
||||
// Prepare payload - always include all fields + registrationToken
|
||||
const payload = {
|
||||
username: username.value,
|
||||
email: email.value,
|
||||
fullName: fullName.value,
|
||||
registrationToken: registrationToken.value, // Add registrationToken to payload
|
||||
};
|
||||
|
||||
// 1. Get options from server
|
||||
|
|
|
@ -87,6 +87,12 @@ const $q = useQuasar();
|
|||
|
||||
// Define the structure of settings
|
||||
const settings = ref({
|
||||
General: [
|
||||
{
|
||||
name: 'Registration Token',
|
||||
key: 'REGISTRATION_TOKEN',
|
||||
}
|
||||
],
|
||||
Mantis: [
|
||||
{
|
||||
name: 'Mantis API Key',
|
||||
|
|
|
@ -22,7 +22,7 @@ const routes = [
|
|||
}
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
path: '/register/:token?',
|
||||
name: 'register',
|
||||
component: () => import('pages/RegisterPage.vue'),
|
||||
meta: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue