Skip to content

Commit

Permalink
ADD: E2E; FIX: Security, Tests, Validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniil-Oberlev committed Aug 31, 2024
1 parent cf533ab commit e4ab528
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 191 deletions.
26 changes: 26 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Удалите директории и файлы, которые не нужны в образе
node_modules
/.next/
/build
.DS_Store
.vscode/
package-lock.json
test-results/
.env.development
.env.production
next-env.d.ts
storybook.log

# Локальные файлы
*.log
*.tmp
*.swp
*.swo

# Скрытые директории
.git/

# Тесты
/tests/
*.spec.js
*.test.js
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
AUTH_API_URL=http://localhost:4444
JWT_SECRET=secret123
NODE_ENV=production
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
AUTH_API_URL=
JWT_SECRET=
NODE_ENV=
45 changes: 40 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,44 @@
FROM node:18-alpine
# Этап 1: Билд
FROM node:18-alpine AS builder

# Устанавливаем рабочую директорию
WORKDIR /app
COPY yarn.lock ./
RUN yarn
COPY . .

# Копируем только необходимые файлы для установки зависимостей
COPY yarn.lock package.json ./
RUN yarn install --ignore-scripts

# Копируем только исходный код и конфигурационные файлы
COPY src/ ./src/
COPY public/ ./public/
COPY tsconfig.json ./

# Собираем проект
RUN yarn build

# Этап 2: Прод
FROM node:18-alpine

# Создаем нового пользователя и группу без прав суперпользователя
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Устанавливаем рабочую директорию
WORKDIR /app

# Копируем собранные файлы из этапа сборки
COPY --from=builder /app/build ./build

# Изменяем владельца файлов приложения на нового пользователя
RUN chown -R appuser:appgroup /app

# Переключаемся на нового пользователя
USER appuser

# Устанавливаем переменную окружения
ENV NODE_ENV=production
CMD ["yarn", "start"]

# Открываем порт приложения
EXPOSE 3000

# Команда для запуска приложения
CMD ["yarn", "start"]
8 changes: 0 additions & 8 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,5 @@ export default defineConfig({
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
{
name: 'Google Chrome',
use: { ...devices['Desktop Chrome'], channel: 'chrome' },
},
],
})
111 changes: 46 additions & 65 deletions src/components/Templates/Login/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
'use client'

import Atom from '@/components/atoms'
import { useAuthForm } from '@/hooks/useAuthForm'
import { useFormField } from '@/hooks/useFormField'
import styles from '@/styles/(auth)/Auth.module.css'
import AuthPageTemplate from '../common/AuthPageTemplate'

const Login = () => {
const emailField = useFormField('')
const passwordField = useFormField('')

const formValues = {
email: emailField.value,
password: passwordField.value,
}

const {
isFormValid,
isSubmitting,
Expand All @@ -28,68 +25,52 @@ const Login = () => {
await handleSubmit(e)
}

const formFields = (
<>
<Atom.InputField
id="email"
label="Email"
type="email"
placeholder="example@example.ru"
value={emailField.value}
error={emailError}
touched={emailField.touched}
onChange={(e) =>
emailField.handleChange(e as React.ChangeEvent<HTMLInputElement>)
}
onBlur={(e) =>
emailField.handleBlur(e as React.FocusEvent<HTMLInputElement>)
}
autoComplete="email"
/>
<Atom.InputField
id="password"
label="Пароль"
type="password"
value={passwordField.value}
error={passwordError}
touched={passwordField.touched}
onChange={(e) =>
passwordField.handleChange(e as React.ChangeEvent<HTMLInputElement>)
}
onBlur={(e) =>
passwordField.handleBlur(e as React.FocusEvent<HTMLInputElement>)
}
autoComplete="current-password"
/>
</>
)

return (
<div className={styles.container}>
<div>
<h1 className={styles.title}>Вход</h1>
<p className={styles.subtitle}>Войдите в свой аккаунт</p>
</div>
<form
onSubmit={handleFormSubmit}
autoComplete="on"
className={styles.form}
>
<Atom.InputField
id="email"
label="Email"
type="email"
placeholder="example@example.ru"
value={emailField.value}
error={emailError}
touched={emailField.touched}
onChange={(e) =>
emailField.handleChange(e as React.ChangeEvent<HTMLInputElement>)
}
onBlur={(e) =>
emailField.handleBlur(e as React.FocusEvent<HTMLInputElement>)
}
autoComplete="email"
/>
<Atom.InputField
id="password"
label="Пароль"
type="password"
value={passwordField.value}
error={passwordError}
touched={passwordField.touched}
onChange={
passwordField.handleChange as (
e:
| React.ChangeEvent<HTMLInputElement>
| React.ChangeEvent<HTMLSelectElement>,
) => void
}
onBlur={
passwordField.handleBlur as (
e:
| React.FocusEvent<HTMLInputElement>
| React.FocusEvent<HTMLSelectElement>,
) => void
}
autoComplete="current-password"
/>
{submissionError && (
<div className={styles.error}>{submissionError}</div>
)}
<Atom.Button
variant="primary"
type="submit"
disabled={!isFormValid || isSubmitting}
>
Вход
</Atom.Button>
</form>
</div>
<AuthPageTemplate
title="Вход"
subtitle="Войдите в свой аккаунт"
formFields={formFields}
submissionError={submissionError}
isFormValid={isFormValid}
isSubmitting={isSubmitting}
onSubmit={handleFormSubmit}
/>
)
}

Expand Down
Loading

0 comments on commit e4ab528

Please sign in to comment.