Skip to content

Commit fe213b8

Browse files
authored
Fourth frontend features and some backend fixes (#74)
1 parent afb1d69 commit fe213b8

File tree

35 files changed

+447
-56
lines changed

35 files changed

+447
-56
lines changed

backend/config/crypto/ca.cnf

+15
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,18 @@ authorityKeyIdentifier = keyid:always,issuer
1919
basicConstraints = critical, CA:true
2020
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
2121

22+
[req_ext]
23+
subjectAltName = @alt_names
24+
25+
[alt_names]
26+
DNS.1 = localhost
27+
DNS.2 = authik-0.dating.se.ifmo.ru
28+
DNS.3 = authik-1.dating.se.ifmo.ru
29+
DNS.4 = authik-2.dating.se.ifmo.ru
30+
DNS.5 = matchmaker-0.dating.se.ifmo.ru
31+
DNS.6 = matchmaker-1.dating.se.ifmo.ru
32+
DNS.7 = matchmaker-2.dating.se.ifmo.ru
33+
DNS.8 = people-0.dating.se.ifmo.ru
34+
DNS.9 = people-1.dating.se.ifmo.ru
35+
DNS.10 = people-2.dating.se.ifmo.ru
36+
DNS.11 = server.dc1.consul

backend/config/crypto/keys.bash

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ENV="$2"
77

88
ALIAS="itmo-dating"
99
ALIAS_BACKEND="$ALIAS-backend"
10+
ALIAS_EXTERNAL="$ALIAS-external"
1011

1112
VALIDITY=1
1213
PASSWORD="$ITMO_DATING_KEY_STORE_PASSWORD"
@@ -71,6 +72,9 @@ function generate() {
7172
-deststoretype JKS \
7273
-destkeystore "$ALIAS_BACKEND.jks" \
7374
-deststorepass "$PASSWORD"
75+
76+
echo "Copying PKCS12 as external certificate"
77+
cp "$ALIAS_BACKEND.p12" "$ALIAS_EXTERNAL.p12"
7478
}
7579

7680
function copy() {
@@ -92,6 +96,7 @@ function distribute() {
9296

9397
echo "Copying package to the gateway..."
9498
copy "$GATEWAY_INSTALL_PATH" "$ALIAS_BACKEND.p12"
99+
copy "$GATEWAY_INSTALL_PATH" "$ALIAS_EXTERNAL.p12"
95100

96101
echo "Copying keys to the consul..."
97102
copy "$CONSUL_INSTALL_PATH" "$ALIAS_BACKEND.key"

backend/consul/Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ RUN chmod -R 755 /consul/config && \
1212
chmod 644 /consul/config/itmo-dating-backend.crt && \
1313
chmod 644 /consul/config/itmo-dating-backend-ca.crt && \
1414
chmod 644 /consul/config/consul.hcl
15+
16+
CMD ["sh", "./consul/run.sh"]

backend/consul/config/consul.hcl

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ acl {
1414
enable_token_persistence = true
1515
}
1616

17+
limits {
18+
http_max_conns_per_client = 400
19+
}
20+
1721
data_dir = "/opt/consul/data"
1822

1923
ui = true

backend/consul/run.sh

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
#!/bin/sh
22

3-
consul agent -config-file=/consul/config/consul.hcl -bootstrap-expect=1 \
4-
| grep -v "This request used the token query parameter which is deprecated and will be removed"
3+
consul agent -config-file=/consul/config/consul.hcl -bootstrap-expect=1 | grep -v "This request used the token query parameter which is deprecated and will be removed"

backend/gateway/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ dependencies {
77

88
implementation(libs.org.springframework.boot.spring.boot)
99
implementation(libs.org.springframework.cloud.spring.cloud.starter.gateway)
10-
10+
implementation(libs.org.springframework.spring.web)
1111
implementation(libs.org.springdoc.springdoc.openapi.starter.webflux.ui)
1212

1313
testImplementation(libs.org.springframework.boot.spring.boot.starter.test)

backend/gateway/src/main/kotlin/ru/ifmo/se/dating/gateway/SSLContextConfig.kt backend/gateway/src/main/kotlin/ru/ifmo/se/dating/gateway/ClientSSLContextConfig.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ import javax.net.ssl.KeyManagerFactory
1212
import javax.net.ssl.TrustManagerFactory
1313

1414
@Configuration
15-
class SSLContextConfig(
16-
@Value("\${server.ssl.key-store-type}")
15+
class ClientSSLContextConfig(
16+
@Value("\${client.ssl.key-store-type}")
1717
private val keyStoreType: String,
1818

19-
@Value("\${server.ssl.key-store}")
19+
@Value("\${client.ssl.key-store}")
2020
private val keyStore: Resource,
2121

22-
@Value("\${server.ssl.key-store-password}")
22+
@Value("\${client.ssl.key-store-password}")
2323
private val keyStorePassword: String,
2424

25-
@Value("\${server.ssl.protocol}")
25+
@Value("\${client.ssl.protocol}")
2626
private val sslProtocol: String,
2727
) {
2828
@Bean

backend/foundation/src/main/kotlin/ru/ifmo/se/dating/spring/api/CorsFilter.kt backend/gateway/src/main/kotlin/ru/ifmo/se/dating/gateway/CorsFilter.kt

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package ru.ifmo.se.dating.spring.api
1+
package ru.ifmo.se.dating.gateway
22

33
import org.springframework.http.HttpMethod
44
import org.springframework.http.HttpStatus
@@ -13,11 +13,15 @@ class CorsFilter : WebFilter {
1313
// FIXME
1414
override fun filter(ctx: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
1515
ctx.response.headers.add("Access-Control-Allow-Origin", "*")
16-
ctx.response.headers.add("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS")
16+
ctx.response.headers.add(
17+
"Access-Control-Allow-Methods",
18+
"GET, PUT, POST, PATCH, DELETE, OPTIONS"
19+
)
1720
ctx.response.headers.add(
1821
"Access-Control-Allow-Headers",
19-
"DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With," +
20-
"If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range"
22+
// "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With," +
23+
// "If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Authorization"
24+
"*"
2125
)
2226
if (ctx.request.method == HttpMethod.OPTIONS) {
2327
ctx.response.headers.add("Access-Control-Max-Age", "1728000")

backend/gateway/src/main/resources/application.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,16 @@ server:
9595
ssl:
9696
enabled: true
9797
key-store-type: PKCS12
98-
key-store: classpath:keystore/itmo-dating-backend.p12
98+
key-store: classpath:keystore/itmo-dating-external.p12
9999
key-store-password: ${KEY_STORE_PASSWORD}
100100
protocol: TLSv1.3
101101
enabled-protocols: TLSv1.3
102+
client:
103+
ssl:
104+
key-store-type: PKCS12
105+
key-store: classpath:keystore/itmo-dating-backend.p12
106+
key-store-password: ${KEY_STORE_PASSWORD}
107+
protocol: TLSv1.3
102108
springdoc:
103109
swagger-ui:
104110
path: /swagger-ui.html

backend/gateway/src/test/kotlin/ru/ifmo/se/dating/gateway/SecurityInitializer.kt

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class SecurityInitializer :
1212
override fun initialize(ctx: ConfigurableApplicationContext) {
1313
TestPropertyValues.of(
1414
"server.ssl.key-store-password=$keyStorePassword",
15+
"client.ssl.key-store-password=$keyStorePassword",
1516
).applyTo(ctx.environment)
1617
}
1718
}

backend/matchmaker/src/main/kotlin/ru/ifmo/se/dating/matchmaker/security/MatchmakerSecuredPaths.kt

+1
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ class MatchmakerSecuredPaths : SpringSecuredPaths {
1414
Path("/api/**"),
1515
Not(Path("/api/people/{person_id}", HttpMethod.PUT)),
1616
Not(Path("/api/monitoring/healthcheck", HttpMethod.GET)),
17+
Not(Path("/api/suggestions", HttpMethod.OPTIONS)),
1718
)
1819
}

backend/starter-service-discovery/src/main/resources/application-service-discovery.yml

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ spring:
1616
instance-id: instance-${HOSTNAME}
1717
heartbeat:
1818
enabled: true
19+
ttl: 30
20+
catalog-services-watch-delay: 5000
1921
management:
2022
health:
2123
consul:

compose.yml

-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ services:
8585
image: ghcr.io/secs-dev/itmo-dating-consul:latest
8686
build:
8787
context: ./backend/consul
88-
command: sh ./consul/run.sh
8988
hostname: server.dc1.consul
9089
ports:
9190
- "127.0.0.1:8500:8500/tcp"

frontend/.eslintrc.cjs

+9
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,14 @@ module.exports = {
2727
plugins: ['@typescript-eslint', 'react'],
2828
rules: {
2929
'react/react-in-jsx-scope': 0,
30+
'no-unused-vars': 'off',
31+
'@typescript-eslint/no-unused-vars': [
32+
'warn', // or "error"
33+
{
34+
argsIgnorePattern: '^_',
35+
varsIgnorePattern: '^_',
36+
caughtErrorsIgnorePattern: '^_',
37+
},
38+
],
3039
},
3140
}

frontend/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ COPY package*.json ./
66

77
RUN npm install
88

9-
# COPY .cert ./.cert
9+
COPY .cert ./.cert
1010

1111
COPY dist ./dist
1212

frontend/src/app/routes/ui/index.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Route } from 'atomic-router-react'
22
import { routes } from '../api'
3-
import { Registration, Home, Main } from '@/pages'
3+
import { Registration, Main } from '@/pages'
4+
import { Welcome } from '@/pages/welcome/ui/Welcome.tsx'
45

56
export const Routes = () => (
67
<>
7-
<Route route={routes.home} view={Home} />
8+
<Route route={routes.home} view={Welcome} />
89
<Route route={routes.registration} view={Registration} />
910
<Route route={routes.main} view={Main} />
1011
</>

frontend/src/entities/person-patch/model/PersonPatch.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
export interface PersonPatch {
2-
status: string
3-
firstName: string
4-
lastName: string
5-
interests: Topic[]
6-
height: number
7-
birthday: string
8-
facultyId: number
9-
locationId: number
2+
status: string | null
3+
firstName: string | null
4+
lastName: string | null
5+
interests: Topic[] | null
6+
height: number | null
7+
birthday: string | null
8+
facultyId: number | null
9+
locationId: number | null
1010
}
1111

1212
export interface Topic {

frontend/src/entities/person/model/Person.ts

+13
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,16 @@ export interface Person {
1515
faculty: string
1616
location: Location
1717
}
18+
19+
export interface PersonLegacy {
20+
status: string
21+
userId: number
22+
firstName: string
23+
zodiac: string
24+
lastName: string
25+
interests: Interest[]
26+
height: number
27+
birthday: Date
28+
facultyId: number
29+
locationId: number
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface Coordinates {
2+
latitude: number
3+
longitude: number
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Coordinates } from './Coordinates.ts'
2+
3+
export interface Location {
4+
id: number
5+
name: string
6+
coordinates: Coordinates
7+
}

frontend/src/entities/registration-data/model/RegistartionData.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { Interest } from './interest.ts'
22
import { Picture } from './picture.ts'
33

44
export type RegistrationData = {
5-
tgId: string
6-
name: string
7-
surname: string
8-
height: number
9-
faculty: string
10-
birthday: Date
11-
pictures: Picture[]
12-
interests: Interest[]
5+
tgId: string | null
6+
name: string | null
7+
surname: string | null
8+
height: number | null
9+
facultyId: number | null
10+
birthday: Date | null
11+
pictures: Picture[] | null
12+
interests: Interest[] | null
13+
locationId: number | null
1314
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface Faculty {
2+
id: number
3+
longName: string
4+
}

frontend/src/features/authentication/api/authFx.ts

+28
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ import { AuthState, initialAuthState } from '@/entities'
77
import { backendAuthikUrl } from '@/shared/api'
88

99
export const $authStore = createStore<AuthState>(initialAuthState)
10+
export const $userIdStore = createStore<number | null>(null)
11+
12+
export const $userRegisteredStore = createStore<boolean>(false)
1013

1114
persist({ store: $authStore, key: 'authStore' })
15+
persist({ store: $userIdStore, key: 'userIdStore' })
16+
persist({ store: $userRegisteredStore, key: 'userRegisteredStore' })
1217

1318
export const authFx = createEffect<AuthRequest, AuthState, Error>({
1419
handler: async (authReq) => {
@@ -49,3 +54,26 @@ $authStore.on(authFx.failData, (_, error) => ({
4954
loading: false,
5055
error: error.message,
5156
}))
57+
58+
export const userIdFx = createEffect<number | null, number | null, Error>({
59+
handler: async (x) => {
60+
if (x == null) throw Error('x is null')
61+
return x
62+
},
63+
})
64+
65+
export const userRegisteredFx = createEffect<boolean, boolean, Error>({
66+
handler: async (x) => {
67+
if (!x) throw Error('user not registered')
68+
return x
69+
},
70+
})
71+
72+
$userIdStore.on(userIdFx.doneData, (_, result) => result)
73+
$userIdStore.on(userIdFx.failData, (_, __) => {
74+
return null
75+
})
76+
$userRegisteredStore.on(userRegisteredFx.doneData, (_, result) => result)
77+
$userRegisteredStore.on(userRegisteredFx.failData, (_, __) => {
78+
return false
79+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import axios from 'axios'
2+
import React from 'react'
3+
import { backendPeopleUrl } from '@/shared/api'
4+
import { Faculty } from '@/entities/registration-data/model/faculty.ts'
5+
6+
export function getFaculties(
7+
setFaculties: React.Dispatch<React.SetStateAction<Array<Faculty>>>,
8+
) {
9+
const url = `${backendPeopleUrl}/api/faculties`
10+
11+
axios
12+
.get(url)
13+
.then((response) => {
14+
console.log(response.data)
15+
//FIXME after integration with backend
16+
setFaculties(response.data)
17+
})
18+
.catch((error) => {
19+
console.error('Error getting faculties: ', error)
20+
//TODO remove after integration with backend
21+
setFaculties([{ id: 1, longName: 'piict' }])
22+
})
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import axios from 'axios'
2+
import React from 'react'
3+
import { backendPeopleUrl } from '@/shared/api'
4+
import { Location } from '@/entities/registration-data/model/Location.ts'
5+
6+
export function getLocations(
7+
setLocations: React.Dispatch<React.SetStateAction<Array<Location>>>,
8+
) {
9+
const url = `${backendPeopleUrl}/api/locations`
10+
11+
axios
12+
.get(url)
13+
.then((response) => {
14+
console.log(response.data)
15+
//FIXME after integration with backend
16+
setLocations(response.data)
17+
})
18+
.catch((error) => {
19+
console.error('Error getting locations: ', error)
20+
//TODO remove after integration with backend
21+
setLocations([
22+
{
23+
id: 1,
24+
name: 'ITMO University, Kronverkskiy Avenue',
25+
coordinates: {
26+
latitude: 59.957478,
27+
longitude: 30.308014,
28+
},
29+
},
30+
])
31+
})
32+
}

0 commit comments

Comments
 (0)