diff --git a/Components/UI/Layout/Header/Nav/Nav.js b/Components/UI/Layout/Header/Nav/Nav.js index ecde380..24d035b 100644 --- a/Components/UI/Layout/Header/Nav/Nav.js +++ b/Components/UI/Layout/Header/Nav/Nav.js @@ -38,7 +38,7 @@ export default function Nav() {
-
+
{status === 'authenticated' && data.user.name}
diff --git a/Components/UI/Layout/Header/Nav/Nav.module.css b/Components/UI/Layout/Header/Nav/Nav.module.css index 675aa7e..5b8c396 100644 --- a/Components/UI/Layout/Header/Nav/Nav.module.css +++ b/Components/UI/Layout/Header/Nav/Nav.module.css @@ -10,6 +10,10 @@ align-items: center; } +.username::first-letter { + text-transform: capitalize; +} + .account { background: none; border: none; diff --git a/Dockerfile b/Dockerfile index 4ece11c..07615dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN apt-get update && apt-get install -y \ RUN groupadd -g ${GID} borgwarehouse && useradd -m -u ${UID} -g ${GID} borgwarehouse -RUN cp /etc/ssh/sshd_config /etc/ssh/moduli /home/borgwarehouse/ +RUN cp /etc/ssh/moduli /home/borgwarehouse/ WORKDIR /home/borgwarehouse/app @@ -47,6 +47,7 @@ COPY --from=builder --chown=borgwarehouse:borgwarehouse /app/public ./public COPY --from=builder --chown=borgwarehouse:borgwarehouse /app/.next/static ./.next/static COPY --from=builder --chown=borgwarehouse:borgwarehouse /app/docker/supervisord.conf ./ COPY --from=builder --chown=borgwarehouse:borgwarehouse /app/docker/rsyslog.conf /etc/rsyslog.conf +COPY --from=builder --chown=borgwarehouse:borgwarehouse /app/docker/sshd_config ./ USER borgwarehouse diff --git a/docker/docker-bw-init.sh b/docker/docker-bw-init.sh index 359af94..3473647 100755 --- a/docker/docker-bw-init.sh +++ b/docker/docker-bw-init.sh @@ -17,7 +17,11 @@ init_ssh_server() { if [ -z "$(ls -A /etc/ssh)" ]; then print_green "/etc/ssh is empty, generating SSH host keys..." ssh-keygen -A - cp /home/borgwarehouse/sshd_config /home/borgwarehouse/moduli /etc/ssh/ + cp /home/borgwarehouse/moduli /etc/ssh/ + fi + if [ ! -f "/etc/ssh/sshd_config" ]; then + print_green "sshd_config not found in your volume, copying the default one..." + cp /home/borgwarehouse/app/sshd_config /etc/ssh/ fi } diff --git a/docker/sshd_config b/docker/sshd_config new file mode 100644 index 0000000..748e991 --- /dev/null +++ b/docker/sshd_config @@ -0,0 +1,32 @@ +Port 22 +PidFile /home/borgwarehouse/tmp/sshd.pid +AllowUsers borgwarehouse +LogLevel INFO +SyslogFacility AUTH + +# Security +Protocol 2 +PermitRootLogin no +PasswordAuthentication no +ChallengeResponseAuthentication no +AuthenticationMethods publickey +MaxAuthTries 2 +MaxStartups 2:30:10 +LoginGraceTime 30 +UsePAM no + +# Useless options for BorgWarehouse +PrintMotd no +UseDNS no +AllowTcpForwarding no +X11Forwarding no +PermitTTY no + +# Ciphers +Ciphers aes256-ctr,aes192-ctr,aes128-ctr +MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com + +# With low bandwidth or huge backup, uncomment the following lines to avoid SSH timeout (Broken pipe). +#ClientAliveInterval 600 +#ClientAliveCountMax 0 + diff --git a/docker/supervisord.conf b/docker/supervisord.conf index c75002d..0930b95 100644 --- a/docker/supervisord.conf +++ b/docker/supervisord.conf @@ -7,7 +7,7 @@ logfile_maxbytes=10MB logfile_backups=5 [program:sshd] -command=/usr/sbin/sshd -D -e -o PidFile=/home/borgwarehouse/tmp/sshd.pid -o SyslogFacility=AUTH -o LogLevel=INFO -o PasswordAuthentication=no -o ChallengeResponseAuthentication=no -o UsePAM=no -o PermitRootLogin=no +command=/usr/sbin/sshd -D -e -f /etc/ssh/sshd_config stdout_logfile=/home/borgwarehouse/tmp/sshd.log stdout_logfile_maxbytes=10MB stdout_logfile_backups=5 diff --git a/package-lock.json b/package-lock.json index 06a04f1..6cf3fba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "borgwarehouse", - "version": "2.1.0", + "version": "2.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "borgwarehouse", - "version": "2.1.0", + "version": "2.2.0", "dependencies": { "@tabler/icons-react": "^2.47.0", "bcryptjs": "^2.4.3", diff --git a/package.json b/package.json index 486c1cc..18edb24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "borgwarehouse", - "version": "2.1.0", + "version": "2.2.0", "private": true, "scripts": { "dev": "next dev", diff --git a/pages/api/auth/[...nextauth].js b/pages/api/auth/[...nextauth].js index f35ac65..1dcad01 100644 --- a/pages/api/auth/[...nextauth].js +++ b/pages/api/auth/[...nextauth].js @@ -5,11 +5,20 @@ import { verifyPassword } from '../../../helpers/functions/auth'; import fs from 'fs'; import path from 'path'; +const logLogin = async (message, req, success = false) => { + const ipAddress = req.headers['x-forwarded-for'] || 'unknown'; + if (success) { + console.log(`Login success from ${ipAddress} with user ${message}`); + } else { + console.log(`Login failed from ${ipAddress} : ${message}`); + } +}; + ////Use if need getServerSideProps and therefore getServerSession export const authOptions = { providers: [ CredentialsProvider({ - async authorize(credentials) { + async authorize(credentials, req) { const { username, password } = credentials; //Read the users file //Find the absolute path of the json directory @@ -42,8 +51,9 @@ export const authOptions = { //Step 1 : does the user exist ? const userIndex = usersList .map((user) => user.username) - .indexOf(username); + .indexOf(username.toLowerCase()); if (userIndex === -1) { + await logLogin(`Bad username ${req.body.username}`, req); throw new Error('Incorrect credentials.'); } const user = usersList[userIndex]; @@ -51,6 +61,10 @@ export const authOptions = { //Step 2 : Is the password correct ? const isValid = await verifyPassword(password, user.password); if (!isValid) { + await logLogin( + `Wrong password for ${req.body.username}`, + req + ); throw new Error('Incorrect credentials.'); } @@ -62,6 +76,7 @@ export const authOptions = { roles: user.roles, }; + await logLogin(req.body.username, req, true); return account; }, }), diff --git a/pages/login.js b/pages/login.js index 50e2db6..c96338e 100644 --- a/pages/login.js +++ b/pages/login.js @@ -99,33 +99,24 @@ export default function Login() { placeholder='Username' className='signInInput' {...register('username', { - required: true, + required: 'This field is required.', + pattern: { + value: /^[^\s]+$/g, + message: 'No space allowed.', + }, })} /> - {errors.email && - errors.email.type === 'required' && ( - - This field is required. - - )} - {errors.email && - errors.email.type === 'pattern' && ( - - Incorrect email address format. - - )} + {errors.username && ( + + {errors.username.message} + + )}

{errors.password && ( @@ -144,7 +135,7 @@ export default function Login() { marginTop: '3px', }} > - This field is required. + {errors.password.message} )}