mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
feat: add username and email check in frontend
This commit is contained in:
1 parent
30aeacaf06
commit
c5ccf03ac5
15 files changed
+95
-64
No files matched your search
@@ -4,10 +4,12 @@ WORKDIR /app
|
|||||||
COPY package.json yarn.lock ./
|
COPY package.json yarn.lock ./
|
||||||
COPY app/package.json ./app/package.json
|
COPY app/package.json ./app/package.json
|
||||||
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
||||||
|
COPY packages/utils/package.json ./packages/utils/package.json
|
||||||
RUN yarn install --frozen-lockfile
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
COPY app ./app
|
COPY app ./app
|
||||||
COPY packages/file-graph ./packages/file-graph
|
COPY packages/file-graph ./packages/file-graph
|
||||||
|
COPY packages/utils ./packages/utils
|
||||||
RUN yarn build
|
RUN yarn build
|
||||||
|
|
||||||
# Production stage
|
# Production stage
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ WORKDIR /app
|
|||||||
COPY package.json yarn.lock ./
|
COPY package.json yarn.lock ./
|
||||||
COPY app/package.json ./app/package.json
|
COPY app/package.json ./app/package.json
|
||||||
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
||||||
|
COPY packages/utils/package.json ./packages/utils/package.json
|
||||||
RUN yarn install --frozen-lockfile
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
WORKDIR /app/app
|
WORKDIR /app/app
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@linux-odyssey/file-graph": "*",
|
"@linux-odyssey/file-graph": "*",
|
||||||
|
"@linux-odyssey/utils": "*",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const clearError = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
clearError()
|
if (errorMessage.value) return
|
||||||
try {
|
try {
|
||||||
emit('onSubmit', {
|
emit('onSubmit', {
|
||||||
username: username.value,
|
username: username.value,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import { isValidEmail, isValidUsername } from '@linux-odyssey/utils'
|
||||||
import AuthForm from '../components/AuthForm.vue'
|
import AuthForm from '../components/AuthForm.vue'
|
||||||
import Background from '../components/DynamicBackground.vue'
|
import Background from '../components/DynamicBackground.vue'
|
||||||
|
|
||||||
@@ -26,21 +27,35 @@ function handleRegister({ username, email, password, success, error }) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// async function check({ username, password, email }) {
|
async function check({ username, email, error }) {
|
||||||
// try {
|
if (username && !isValidUsername(username)) {
|
||||||
// const res = await api.get('/auth/check-username', {
|
error('Invalid username.')
|
||||||
// params: { username },
|
return
|
||||||
// })
|
}
|
||||||
// const { type, available } = res.data
|
if (email && !isValidEmail(email)) {
|
||||||
// } catch (err) {
|
error('Invalid email.')
|
||||||
// if (err.response?.status === 400) {
|
return
|
||||||
// errorMessage.value = 'Invalid username or email.'
|
}
|
||||||
// return
|
if (!username && !email) {
|
||||||
// }
|
return
|
||||||
// errorMessage.value = 'Something went wrong.'
|
}
|
||||||
// console.error(err)
|
try {
|
||||||
// }
|
const res = await api.get('/auth/check-username', {
|
||||||
// }
|
params: { username },
|
||||||
|
})
|
||||||
|
const { type, available } = res.data
|
||||||
|
if (!available) {
|
||||||
|
error(`${type} already exists.`)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.response?.status === 400) {
|
||||||
|
error('Invalid username or email.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.error(err)
|
||||||
|
error('Something went wrong.')
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="relative w-screen h-screen">
|
<div class="relative w-screen h-screen">
|
||||||
@@ -49,7 +64,11 @@ function handleRegister({ username, email, password, success, error }) {
|
|||||||
class="h-screen w-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
|
class="h-screen w-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
|
||||||
>
|
>
|
||||||
<div class="h-2/3 w-1/3">
|
<div class="h-2/3 w-1/3">
|
||||||
<AuthForm @onSubmit="handleRegister" :isRegister="true" />
|
<AuthForm
|
||||||
|
@onSubmit="handleRegister"
|
||||||
|
@onChange="check"
|
||||||
|
:isRegister="true"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ services:
|
|||||||
- internal
|
- internal
|
||||||
volumes:
|
volumes:
|
||||||
- ./app:/app/app
|
- ./app:/app/app
|
||||||
- ./packages/file-graph:/app/packages/file-graph
|
- ./packages:/app/packages
|
||||||
backend:
|
backend:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
export function isValidUsername(username) {
|
||||||
|
// Define a regular expression pattern for a valid Linux username.
|
||||||
|
const usernamePattern = /^[a-z][a-z0-9_-]*$/
|
||||||
|
|
||||||
|
// Test the username against the pattern.
|
||||||
|
if (!usernamePattern.test(username)) return false
|
||||||
|
|
||||||
|
// check if the username is between 1 and 32 characters
|
||||||
|
if (username.length < 4 || username.length > 32) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const reservedWords = [
|
||||||
|
'root',
|
||||||
|
'admin',
|
||||||
|
'administrator',
|
||||||
|
'sysadmin',
|
||||||
|
'system',
|
||||||
|
'daemon',
|
||||||
|
'bin',
|
||||||
|
'nobody',
|
||||||
|
'nogroup',
|
||||||
|
'guest',
|
||||||
|
'user',
|
||||||
|
]
|
||||||
|
if (reservedWords.includes(username)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isValidEmail(email) {
|
||||||
|
// Define a regular expression pattern for a valid email address.
|
||||||
|
const emailPattern = /^[\w-.+]+@([\w][\w-]*\.)+[\w-]{2,}$/
|
||||||
|
|
||||||
|
// Test the email against the pattern.
|
||||||
|
return emailPattern.test(email)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { isValidEmail, isValidUsername } from '../../src/utils/auth'
|
import { isValidEmail, isValidUsername } from './auth.js'
|
||||||
|
|
||||||
test('check valid username', () => {
|
test('check valid username', () => {
|
||||||
const valid = ['alex', 'alex123', 'john_doe', 'john-doe', 'rudeus']
|
const valid = ['alex', 'alex123', 'john_doe', 'john-doe', 'rudeus']
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { isValidEmail, isValidUsername } from './auth.js'
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "@linux-odyssey/utils",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"exports": "./index.js",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
@@ -4,10 +4,12 @@ WORKDIR /app
|
|||||||
COPY ./package.json yarn.lock ./
|
COPY ./package.json yarn.lock ./
|
||||||
COPY server/package.json ./server/package.json
|
COPY server/package.json ./server/package.json
|
||||||
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
||||||
|
COPY packages/utils/package.json ./packages/utils/package.json
|
||||||
RUN yarn install --frozen-lockfile --production
|
RUN yarn install --frozen-lockfile --production
|
||||||
|
|
||||||
COPY ./server ./server
|
COPY ./server ./server
|
||||||
COPY packages/file-graph ./packages/file-graph
|
COPY packages/file-graph ./packages/file-graph
|
||||||
|
COPY packages/utils ./packages/utils
|
||||||
COPY quests ./quests
|
COPY quests ./quests
|
||||||
|
|
||||||
WORKDIR /app/server
|
WORKDIR /app/server
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ WORKDIR /app
|
|||||||
COPY package.json yarn.lock ./
|
COPY package.json yarn.lock ./
|
||||||
COPY server/package.json ./server/package.json
|
COPY server/package.json ./server/package.json
|
||||||
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
COPY packages/file-graph/package.json ./packages/file-graph/package.json
|
||||||
|
COPY packages/utils/package.json ./packages/utils/package.json
|
||||||
RUN yarn install --frozen-lockfile
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
COPY server/nodemon.json ./server/nodemon.json
|
COPY server/nodemon.json ./server/nodemon.json
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@linux-odyssey/file-graph": "*",
|
"@linux-odyssey/file-graph": "*",
|
||||||
|
"@linux-odyssey/utils": "*",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"commander": "^11.0.0",
|
"commander": "^11.0.0",
|
||||||
"connect-mongo": "^5.0.0",
|
"connect-mongo": "^5.0.0",
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
|
import { isValidEmail, isValidUsername } from '@linux-odyssey/utils'
|
||||||
import User from '../../models/user.js'
|
import User from '../../models/user.js'
|
||||||
import {
|
import { genJWT, hashPassword } from '../../utils/auth.js'
|
||||||
genJWT,
|
|
||||||
hashPassword,
|
|
||||||
isValidEmail,
|
|
||||||
isValidUsername,
|
|
||||||
} from '../../utils/auth.js'
|
|
||||||
|
|
||||||
export async function issueToken(req, res) {
|
export async function issueToken(req, res) {
|
||||||
const { user } = req
|
const { user } = req
|
||||||
|
|||||||
@@ -47,42 +47,3 @@ export function verifyJWT(token) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isValidUsername(username) {
|
|
||||||
// Define a regular expression pattern for a valid Linux username.
|
|
||||||
const usernamePattern = /^[a-z][a-z0-9_-]*$/
|
|
||||||
|
|
||||||
// Test the username against the pattern.
|
|
||||||
if (!usernamePattern.test(username)) return false
|
|
||||||
|
|
||||||
// check if the username is between 1 and 32 characters
|
|
||||||
if (username.length < 4 || username.length > 32) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
const reservedWords = [
|
|
||||||
'root',
|
|
||||||
'admin',
|
|
||||||
'administrator',
|
|
||||||
'sysadmin',
|
|
||||||
'system',
|
|
||||||
'daemon',
|
|
||||||
'bin',
|
|
||||||
'nobody',
|
|
||||||
'nogroup',
|
|
||||||
'guest',
|
|
||||||
'user',
|
|
||||||
]
|
|
||||||
if (reservedWords.includes(username)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isValidEmail(email) {
|
|
||||||
// Define a regular expression pattern for a valid email address.
|
|
||||||
const emailPattern = /^[\w-.+]+@([\w][\w-]*\.)+[\w-]{2,}$/
|
|
||||||
|
|
||||||
// Test the email against the pattern.
|
|
||||||
return emailPattern.test(email)
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user