136 Commits

Author SHA1 Message Date
66d25e03d1 add traefik oauth forward 2025-01-05 19:14:59 +01:00
d6a685cbcc Merge branch 'main' into feature/rework-deployment-to-docker-compose 2025-01-02 13:27:12 +01:00
Vargha Csongor
47dca8ed3d Merge pull request #10 from vcscsvcscs/feature/restructure-repo
Restructure repo to go standard
2024-12-28 14:02:59 +01:00
42b88e14a7 update images 2024-12-28 13:26:38 +01:00
cbb53d640d switch to main 2024-12-27 12:04:46 +01:00
462168d8ed delete zitadel relations 2024-12-27 11:59:52 +01:00
e4b27d7539 remove zitadel 2024-12-26 13:31:00 +01:00
30e236446a add favicon 2024-12-24 09:59:16 +01:00
62341abf09 remove quotes around admin in zitadel values.yml 2024-12-23 11:28:35 +01:00
bbddd08d24 fix path and add go get to docker 2024-12-22 22:22:05 +01:00
fa4c886300 update 2024-12-22 22:17:14 +01:00
9da42c62cd name lint and test and add go get path 2024-12-22 22:06:38 +01:00
d0f80818b0 change deploy trigger to pr too 2024-12-22 21:59:55 +01:00
677adc1e22 fixup ci 2024-12-22 21:58:50 +01:00
fa7086cd3c comment unused zitadel auths in backend 2024-12-22 21:41:56 +01:00
3bfc20cb21 move frontend to a cmd too for consistency 2024-12-22 21:40:21 +01:00
ebd82475fd update go in docker image 2024-12-22 21:39:54 +01:00
5658c10b56 move backend to new structure 2024-12-22 21:39:36 +01:00
3c601caf02 move auth to auth 2024-12-22 21:33:46 +01:00
cc623b71dc abc to password 2024-10-27 19:28:55 +01:00
9560c339a8 add memgraph password 2024-10-27 19:17:56 +01:00
154bb2de21 tls to memgraph 2024-10-27 19:17:34 +01:00
628140d6f6 fix admin password ref 2024-10-27 17:29:22 +01:00
ff4f4665c4 modify postgres start values 2024-10-27 16:51:10 +01:00
6947132f8d downgrade chart 2024-10-27 16:46:12 +01:00
e8b81e33c2 update postgres initadmin password 2024-10-27 16:40:49 +01:00
8a9d3a6091 fixup strings 2024-10-27 16:34:29 +01:00
17d308ce08 update postgress use 2024-10-27 15:28:49 +01:00
e8d065c3bd update username 2024-10-27 13:49:51 +01:00
65664e1a6e update values memgraph 2024-10-27 13:43:01 +01:00
c336cc09e3 update memgraph values 2024-10-27 13:34:27 +01:00
2124cd4fde add users volume claim to memgraph deployment 2024-10-27 13:30:47 +01:00
77b7249e83 fix cert dns for psql 2024-10-27 13:20:51 +01:00
ca4a8d7361 update memgraph storage size 2024-10-27 13:03:50 +01:00
95a6bf5a70 add secrets to memgraph init 2024-10-27 12:50:04 +01:00
9874dee333 change db host 2024-10-27 12:46:48 +01:00
ed0b9de12a change target revision for current branch 2024-10-27 12:42:45 +01:00
0dece52a55 update pvc for postgre 2024-10-27 12:42:10 +01:00
a64ec65096 update helm details 2024-10-27 12:35:44 +01:00
3ce6721740 rm manifest 2024-10-27 12:32:20 +01:00
d5cc3320ee change chart repo for psql 2024-10-27 12:31:35 +01:00
e14ed71766 update kustomize 2024-10-27 12:11:16 +01:00
b745b49d9b fixup deployment 2024-10-27 12:03:29 +01:00
6ee87d059e switch to psql 2024-10-27 09:53:00 +01:00
708f07a7ef add multiplatform img support 2024-09-21 23:39:10 +02:00
3944a0b8ef backend remove auth 2024-09-21 22:57:33 +02:00
6dc8facd67 Reworked deployment 2024-09-21 22:57:13 +02:00
Vargha Csongor
877557febe Merge pull request #8 from vcscsvcscs/feature/Add-frontend
[Feature] Implement frontend
Work was not finished here, but things will be changed in a future pr
2024-09-21 17:30:25 +02:00
10bee29482 fix small picture bugs 2024-09-21 17:18:28 +02:00
4db7a35271 fix api api communications 2024-05-17 14:03:34 +02:00
069d9317a3 fix person creation 2024-05-17 01:52:58 +02:00
ab2fd071e0 make temporary auth solution 2024-05-17 01:10:14 +02:00
0b1ca6338f Create forward auth 2024-05-17 00:03:52 +02:00
c466587bb5 Fixup Family member add panel tailwind 2024-05-15 23:27:15 +02:00
b292f39da0 fixup frontend 2024-05-15 23:21:04 +02:00
8991c30dd2 update traefik server transport 2024-05-15 22:45:40 +02:00
7a26af537a update cors 2024-05-15 22:45:24 +02:00
1163222406 fix cert names 2024-05-15 21:11:56 +02:00
e8962e2915 fix default tls paths 2024-05-15 21:09:24 +02:00
517ef26598 add on mount to solve issues with func call before load 2024-05-15 09:30:50 +02:00
f2d6bd1f8c add node click handle 2024-05-15 08:42:54 +02:00
321136ae4c fix forms daisy 2024-05-15 08:42:37 +02:00
741286f773 fix redirect url 2024-05-14 23:29:58 +02:00
2c6b21fa77 format 2024-05-14 22:00:21 +02:00
4ac9a4d437 fix function call before load bug 2024-05-14 21:59:06 +02:00
78305e7ca2 fix configs 2024-05-14 21:52:37 +02:00
cb6809b2a4 Add skeleton code to auth service for testing 2024-05-13 21:21:52 +02:00
416b4f0302 update docker image platform in cd 2024-05-13 21:11:10 +02:00
f484a271e2 update docker images 2024-05-13 21:10:17 +02:00
8139673405 Create profile 2024-05-13 19:51:14 +02:00
b13c1228af fix typing 2024-05-05 16:24:15 +02:00
b2ef584057 switch db schema to snake case for better frontend/backend/db integration 2024-05-05 16:13:22 +02:00
a7ad330b27 Change add family member structure 2024-05-05 15:56:48 +02:00
4c8d74ae04 format prettier 2024-05-05 15:56:27 +02:00
f461825234 With required fields only 2024-05-05 12:51:19 +02:00
bae91335fe start family member adding ui implementation 2024-05-05 12:45:52 +02:00
c10a1857a3 Add person panel 2024-05-05 12:21:37 +02:00
6bdbee1271 Add person menu 2024-05-05 12:21:27 +02:00
8ec95c4de1 Add relationship 2024-05-05 12:20:29 +02:00
8176277fcb add edges 2024-05-04 13:58:05 +02:00
d0af8f0250 Add login logic 2024-05-01 13:38:58 +02:00
Vargha Csongor
935b3ac5cf Merge pull request #7 from vcscsvcscs/feature/update-zitadel
update zitadel version
2024-04-29 13:01:55 +02:00
10c9ad393d update version 2024-04-29 13:01:18 +02:00
9f21a36406 Attempt to make things look nice 2024-04-29 12:58:43 +02:00
a28a6fa675 Create person node 2024-04-28 21:05:37 +02:00
2f795d6901 Return whole family tree 2024-04-28 21:05:19 +02:00
Vargha Csongor
5a958840b4 Merge pull request #6 from vcscsvcscs/feature/update-zitadel
Feature/update zitadel
2024-04-22 16:50:44 +02:00
c1df052462 ++ version zitadel 2024-04-22 16:49:11 +02:00
64b9361651 Add daisy ui and tailwind 2024-04-22 15:47:54 +02:00
Vargha Csongor
e5425b1cc8 Merge pull request #5 from vcscsvcscs/feature/add-basic-backend-functionalities
[Feature] Add backend functionalities
2024-04-22 08:39:16 +02:00
5a7e62a183 update ci to only trigger once 2024-04-22 08:38:33 +02:00
5e871cb272 fix some miss conventions 2024-04-22 08:37:21 +02:00
22ca38ad86 fix bidirectional relationships 2024-04-22 08:29:04 +02:00
3ade387d7d view family tree 2024-04-22 08:27:44 +02:00
77042ffdc5 Add verified to Person 2024-04-18 23:10:16 +02:00
5b9b6c53a6 Add ' to query 2024-04-18 23:10:00 +02:00
0b0b138c16 change errors to contain original 2024-04-18 23:09:42 +02:00
304552c2a5 Add ' to query 2024-04-18 23:09:23 +02:00
cf4b79c593 uuid to memgraph compatible 2024-04-18 23:08:52 +02:00
bc7cf7f1a6 create memgraph compatible uuid 2024-04-18 23:08:35 +02:00
e49aba7c58 fix api 2024-04-18 23:07:12 +02:00
01c6e4b0c9 Fix update person 2024-04-18 23:07:03 +02:00
564ef322e3 set uuid in a function after verify 2024-04-18 22:36:06 +02:00
d85d37eb2d Change responses 2024-04-18 22:35:48 +02:00
913042d441 add error logging and modify return 2024-04-18 22:35:32 +02:00
56607b31e5 correct typo 2024-04-18 22:35:02 +02:00
a5822913f6 create Relationship and person 2024-04-18 21:02:04 +02:00
5d03c51097 fix viewPerson query to be secure 2024-04-18 21:01:52 +02:00
5e8cdecca7 change bolt+s protocol to bolt+ssc in default for memgraph 2024-04-18 21:01:33 +02:00
40a70ecc93 Remove wrong driver close 2024-04-18 21:01:01 +02:00
12bb08d6ce fix typo and add handlers to router 2024-04-16 23:16:52 +02:00
eadfcd7afc update person 2024-04-16 23:13:16 +02:00
5d19dad30f change status code 2024-04-16 23:13:08 +02:00
7358ef5db1 delete person 2024-04-16 23:12:54 +02:00
68bd7dec11 update person to string 2024-04-16 23:00:06 +02:00
f10d8a87db verify relationship 2024-04-16 22:59:35 +02:00
72f81214be use snake case file naming convention 2024-04-16 22:45:07 +02:00
47b52d8a33 fix multi direction relationships 2024-04-16 22:27:11 +02:00
2e4cd879b2 delete relationship 2024-04-16 22:26:55 +02:00
ca67dead2b add createRelationship as a handler 2024-04-15 23:56:52 +02:00
162fe47051 create handler files 2024-04-15 23:47:25 +02:00
d49601b871 fix logging in createPerson 2024-04-15 23:46:32 +02:00
f5e95095c7 create relationship 2024-04-15 23:46:11 +02:00
c54b142b70 verify structs 2024-04-15 23:45:51 +02:00
65345e0e76 cypher injection prevention 2024-04-15 23:45:01 +02:00
a34a934bf4 move utilities to remote instead local 2024-04-15 21:13:19 +02:00
73627c7c59 Add utilities to docker files 2024-04-15 21:05:32 +02:00
33aa4945af go mod tidy 2024-04-15 20:50:46 +02:00
3b12f4798c Add Person model 2024-04-14 23:49:33 +02:00
cb6628a83c implement Get person endpoint 2024-04-14 19:21:20 +02:00
a4c1bc56f8 Fix release pipeline tagging 2024-04-14 17:13:59 +02:00
79256f2f10 Merge branch 'main' into feature/add-basic-backend-functionalities 2024-04-14 11:47:32 +02:00
cdea69736d Add init database.go 2024-04-14 11:46:46 +02:00
Vargha Csongor
ffde94d457 Merge pull request #4 from vcscsvcscs/feature/server-and-logger-setup-utilities
Move server and logger setup to utilities module
2024-04-14 11:18:27 +02:00
35f478e24c create memgraph db connection 2024-04-14 11:15:01 +02:00
a6718b2487 update docker build action 2024-04-14 01:25:56 +02:00
119 changed files with 5078 additions and 1177 deletions

View File

@@ -1,9 +1,10 @@
name: Release Auth service to Docker Hub and Deploy to Kubernetes
name: Release Auth service to Docker Hub
on:
push:
pull_request:
paths:
- "auth-service/**"
- "cmd/auth/**"
- "pkg/**"
- "deployment/auth-service/**"
- ".github/workflows/auth-service-cd.yml"
@@ -16,10 +17,10 @@ jobs:
id: create_image_tag
with:
script: |
if (context.issue.number) {
return "pr" + context.issue.number;
} else if(github.ref == 'refs/heads/main') {
if(github.ref == 'refs/heads/main') {
return 'latest';
} else if(context.issue.number) {
return "pr" + context.issue.number;
} else {
return "pr" + (
await github.rest.repos.listPullRequestsAssociatedWithCommit({
@@ -46,6 +47,6 @@ jobs:
uses: docker/build-push-action@v5
with:
push: true
context: "{{defaultContext}}:auth-service"
context: "{{defaultContext}}:cmd/auth"
tags: vcscsvcscs/gheritage-auth-service:${{steps.create_image_tag.outputs.result}}
platforms: linux/arm64/v8
platforms: linux/amd64, linux/arm64

View File

@@ -1,24 +0,0 @@
name: Authentication service Continuous Integration
on:
push:
paths:
- "auth-service/**"
pull_request:
paths:
- "auth-service/**"
jobs:
lint:
uses: ./.github/workflows/go_lint.yml
with:
working-directory: 'auth-service'
build:
needs: lint
uses: ./.github/workflows/go_build.yml
with:
working-directory: 'auth-service'
test:
needs: build
uses: ./.github/workflows/go_test.yml
with:
working-directory: 'auth-service'

View File

@@ -1,9 +1,10 @@
name: Release Backend service to Docker Hub and Deploy to Kubernetes
name: Release Backend service to Docker Hub
on:
push:
pull_request:
paths:
- "backend/**"
- "cmd/backend/**"
- "pkg/**"
- "deployment/backend/**"
- ".github/workflows/backend-cd.yml"
@@ -16,10 +17,10 @@ jobs:
id: create_image_tag
with:
script: |
if (context.issue.number) {
return "pr" + context.issue.number;
} else if(github.ref == 'refs/heads/main') {
if(github.ref == 'refs/heads/main') {
return 'latest';
} else if(context.issue.number) {
return "pr" + context.issue.number;
} else {
return "pr" + (
await github.rest.repos.listPullRequestsAssociatedWithCommit({
@@ -46,6 +47,6 @@ jobs:
uses: docker/build-push-action@v5
with:
push: true
context: "{{defaultContext}}:backend"
context: "{{defaultContext}}:cmd/backend"
tags: vcscsvcscs/gheritage-backend-service:${{steps.create_image_tag.outputs.result}}
platforms: linux/arm64/v8
platforms: linux/amd64, linux/arm64

View File

@@ -1,23 +0,0 @@
name: Backend Continuous Integration
on:
push:
paths:
- "backend/**"
pull_request:
paths:
- "backend/**"
jobs:
lint:
uses: ./.github/workflows/go_lint.yml
with:
working-directory: 'backend'
build:
needs: lint
uses: ./.github/workflows/go_build.yml
with:
working-directory: 'backend'
test:
needs: build
uses: ./.github/workflows/go_test.yml
with:
working-directory: 'backend'

View File

@@ -1,19 +1,15 @@
name: Frontend Continuous Integration
on:
push:
paths:
- "frontend/**"
pull_request:
paths:
- "frontend/**"
- "cmd/frontend/**"
jobs:
lint:
uses: ./.github/workflows/svelte_lint.yml
with:
working-directory: 'frontend'
working-directory: 'cmd/frontend'
build:
needs: lint
uses: ./.github/workflows/svelte_build.yml
with:
working-directory: 'frontend'
working-directory: 'cmd/frontend'

View File

@@ -1,29 +0,0 @@
on:
workflow_call:
inputs:
working-directory:
required: true
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Go 1.22.x'
uses: actions/setup-go@v5
with:
go-version: '1.22.x'
- name: Display Go version
run: go version
- name: Install dependencies
run: |
cd ${{ inputs.working-directory }}
go get
- name: Build
run: |
cd ${{ inputs.working-directory }}
go build .

View File

@@ -1,9 +1,10 @@
name: Go Lint
on:
workflow_call:
inputs:
working-directory:
required: true
type: string
pull_request:
paths:
- "cmd/**"
- "pkg/**"
jobs:
golangci:
@@ -13,10 +14,10 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
go-version: '1.23'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: latest
working-directory: ${{ inputs.working-directory }}
working-directory: .

View File

@@ -1,29 +1,28 @@
name: Go Test
on:
workflow_call:
inputs:
working-directory:
required: true
type: string
pull_request:
paths:
- "cmd/**"
- "pkg/**"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Go 1.22.x'
- name: Setup Go 1.23.x'
uses: actions/setup-go@v5
with:
go-version: '1.22.x'
go-version: '1.23.x'
- name: Display Go version
run: go version
- name: Install dependencies
run: |
cd ${{ inputs.working-directory }}
go get
go get ./...
- name: Run tests
run: |
cd ${{ inputs.working-directory }}
go test ./...

View File

@@ -1,13 +0,0 @@
FROM golang:1.22.2-alpine as build
WORKDIR /app
COPY . .
RUN GOOS=linux GOARCH=arm64 go build -o auth-service
FROM arm64v8/busybox
COPY --from=build /app/auth-service /app/
CMD [ "/app/auth-service" ]

View File

@@ -1,3 +0,0 @@
module github.com/vcscsvcscs/GenerationsHeritage/auth-service
go 1.22.2

View File

@@ -1,5 +0,0 @@
package main
func main() {
}

View File

@@ -1,13 +0,0 @@
FROM golang:1.22.2-alpine as build
WORKDIR /app
COPY . .
RUN GOOS=linux GOARCH=arm64 go build -o backend
FROM busybox
COPY --from=build /app/backend /app/
CMD [ "/app/backend" ]

View File

@@ -1,36 +0,0 @@
module github.com/vcscsvcscs/GenerationsHeritage/backend
go 1.22.2
require (
github.com/gin-gonic/gin v1.9.1
github.com/vcscsvcscs/GenerationsHeritage/utilities v0.0.0-20240413225529-30321ba5d7e7
)
require (
github.com/bytedance/sonic v1.11.3 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.19.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

View File

@@ -1,94 +0,0 @@
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA=
github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/vcscsvcscs/GenerationsHeritage/utilities v0.0.0-20240413225529-30321ba5d7e7 h1:6HOZdgsOt8KojDfNDOyHLwv+Chv90MECxMdP+cKKNv4=
github.com/vcscsvcscs/GenerationsHeritage/utilities v0.0.0-20240413225529-30321ba5d7e7/go.mod h1:8byGXK+Csy5RCmHrvdMIzS8oVuvkr9Ech2PqLrad7os=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@@ -1,107 +0,0 @@
package main
import (
"context"
"errors"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
"github.com/vcscsvcscs/GenerationsHeritage/utilities"
"github.com/vcscsvcscs/GenerationsHeritage/utilities/gin_liveness"
)
var (
cert = flag.String("cert", "./private/keys/cert.pem", "Specify the path of TLS cert")
key = flag.String("key", "./private/keys/key.pem", "Specify the path of TLS key")
httpsPort = flag.String("https", ":443", "Specify port for http secure hosting(example for format :443)")
httpPort = flag.String("http", ":80", "Specify port for http hosting(example for format :80)")
release = flag.Bool("release", false, "Set true to release build")
logToFile = flag.Bool("log-to-file", false, "Set true to log to file")
logToFileAndStd = flag.Bool("log-to-file-and-std", false, "Set true to log to file and std")
requestTimeout = time.Duration(*flag.Int("request-timeout", 20, "Set request timeout in seconds"))
)
func main() {
flag.Parse()
if *release {
gin.SetMode(gin.ReleaseMode)
}
if *logToFileAndStd || *logToFile {
gin.DisableConsoleColor() // Disable Console Color, you don't need console color when writing the logs to file.
path := fmt.Sprintf("private/logs/%02dy_%02dm_%02dd_%02dh_%02dm_%02ds.log", time.Now().Year(), time.Now().Month(), time.Now().Day(), time.Now().Hour(), time.Now().Minute(), time.Now().Second())
logerror1 := os.MkdirAll("private/logs/", 0755)
f, logerror2 := os.Create(path)
if logerror1 != nil || logerror2 != nil {
log.Println("Cant log to file")
} else if *logToFileAndStd {
gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
} else {
gin.DefaultWriter = io.MultiWriter(f)
}
}
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetOutput(gin.DefaultErrorWriter)
hc := gin_liveness.New()
router := gin.Default()
router.GET("/health", hc.HealthCheckHandler())
var server *http.Server
if utilities.FileExists(*cert) && utilities.FileExists(*key) {
server = &http.Server{
Addr: *httpsPort,
Handler: router,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
go func() {
log.Println("Server starts at port ", *httpsPort)
if err := server.ListenAndServeTLS(*cert, *key); err != nil && errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
}()
} else {
server = &http.Server{
Addr: *httpPort,
Handler: router,
ReadTimeout: requestTimeout * time.Second,
WriteTimeout: requestTimeout * time.Second,
}
go func() {
log.Println("Server starts at port ", *httpPort)
if err := server.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
}()
}
// Wait for interrupt signal to gracefully shutdown the server with some time to finish requests.
quit := make(chan os.Signal, 1)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-quit
log.Println("Shutting down server...")
// The context is used to inform the server it has some seconds to finish
// the request it is currently handling
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatal("Server forced to shutdown:", err)
}
log.Println("Server exiting")
}

23
cmd/auth/auth.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/zitadel/zitadel-go/v3/pkg/authorization/oauth"
"github.com/zitadel/zitadel-go/v3/pkg/http/middleware"
)
func auth(mw *middleware.Interceptor[*oauth.IntrospectionContext]) gin.HandlerFunc {
return func(c *gin.Context) {
mw.RequireAuthorization()(http.HandlerFunc(authHTTPHandler(mw, c))).ServeHTTP(c.Writer, c.Request)
}
}
func authHTTPHandler(mw *middleware.Interceptor[*oauth.IntrospectionContext], c *gin.Context) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
authCtx := mw.Context(r.Context())
w.Header().Set("id", authCtx.UserID())
c.JSON(http.StatusOK, gin.H{"id": authCtx.UserID(), "status": "ok"})
}
}

21
cmd/auth/dockerfile Normal file
View File

@@ -0,0 +1,21 @@
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETOS
ARG TARGETARCH
WORKDIR /app
COPY . .
RUN go get ./...
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o auth-service
RUN apk update && apk add ca-certificates && update-ca-certificates
FROM --platform=$TARGETPLATFORM busybox:1.36.1
COPY --from=build /etc/ssl/certs /etc/ssl/certs
COPY --from=build /app/auth-service /app/
CMD [ "/app/auth-service" ]

84
cmd/auth/main.go Normal file
View File

@@ -0,0 +1,84 @@
package main
import (
"context"
"flag"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
utilities "github.com/vcscsvcscs/GenerationsHeritage/pkg"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/gin/healthcheck"
"github.com/zitadel/zitadel-go/v3/pkg/authorization"
"github.com/zitadel/zitadel-go/v3/pkg/authorization/oauth"
"github.com/zitadel/zitadel-go/v3/pkg/http/middleware"
"github.com/zitadel/zitadel-go/v3/pkg/zitadel"
)
var (
cert = flag.String("cert", "/etc/gh-authz/ssl/tls.crt", "Specify the path of TLS cert")
key = flag.String("key", "/etc/gh-authz/ssl/tls.key", "Specify the path of TLS key")
zitadelAccessKey = flag.String("zitadel-access-key", "/etc/gh-authz/zitadel/api-key.json", "Specify the path of Zitadel access key")
httpsPort = flag.String("https", ":443", "Specify port for http secure hosting(example for format :443)")
httpPort = flag.String("http", ":80", "Specify port for http hosting(example for format :80)")
zitadelURI = flag.String("zitadel-uri", "zitadel.varghacsongor.hu", "Specify the Zitadel URI")
release = flag.Bool("release", false, "Set true to release build")
logToFile = flag.Bool("log-to-file", false, "Set true to log to file")
logToFileAndStd = flag.Bool("log-to-file-and-std", false, "Set true to log to file and std")
requestTimeout = time.Duration(*flag.Int("request-timeout", 20, "Set request timeout in seconds"))
)
func main() {
flag.Parse()
if *release {
gin.SetMode(gin.ReleaseMode)
}
utilities.SetupLogger(*logToFileAndStd, *logToFile)
hc := healthcheck.New()
router := gin.Default()
router.Use(gin.Recovery())
ctx := context.Background()
// Initiate the authorization by providing a zitadel configuration and a verifier.
// This example will use OAuth2 Introspection for this, therefore you will also need to provide the downloaded api key.json
authZ, err := authorization.New(ctx, zitadel.New(*zitadelURI), oauth.DefaultAuthorization(*zitadelAccessKey))
if err != nil {
log.Println("zitadel sdk could not initialize", "error", err)
os.Exit(1)
}
// Initialize the HTTP middleware by providing the authorization
mw := middleware.New(authZ)
router.GET("/health", hc.HealthCheckHandler())
router.GET("/auth", auth(mw))
server := utilities.SetupHttpsServer(router, *cert, *key, *httpsPort, *httpPort, requestTimeout)
// Wait for interrupt signal to gracefully shutdown the server with some time to finish requests.
quit := make(chan os.Signal, 1)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-quit
log.Println("Shutting down server...")
// The context is used to inform the server it has some seconds to finish
// the request it is currently handling
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatal("Server forced to shutdown:", err)
}
log.Println("Server exiting")
}

21
cmd/backend/dockerfile Normal file
View File

@@ -0,0 +1,21 @@
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETOS
ARG TARGETARCH
WORKDIR /app
COPY . .
RUN go get ./...
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o backend
RUN apk update && apk add ca-certificates && update-ca-certificates
FROM --platform=$TARGETPLATFORM busybox:1.36.1
COPY --from=build /etc/ssl/certs /etc/ssl/certs
COPY --from=build /app/backend /app/
CMD [ "/app/backend" ]

View File

@@ -0,0 +1,49 @@
package handlers
import (
"encoding/json"
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
)
func CreatePerson(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
if c.Request.Body == nil || c.ContentType() != "application/json" {
log.Printf("ip: %s error: request body is empty or content type is not application/json", c.ClientIP())
c.JSON(http.StatusBadRequest, gin.H{"error": "content type must be application/json and request body must not be empty"})
return
}
var person memgraph.Person
err := json.NewDecoder(c.Request.Body).Decode(&person)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
return
}
if err := person.Verify(); err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": "contains-forbidden-characters"})
return
}
person.ID = c.GetString("id")
rec, err := person.CreatePerson(driver)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": "already-exists"})
return
}
c.JSON(http.StatusCreated, gin.H{"person": rec.AsMap()})
}
}

View File

@@ -0,0 +1,32 @@
package handlers
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
)
func CreateRelationship(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
var relationship memgraph.Relationship
if err := c.ShouldBindJSON(&relationship); err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
rec, err := relationship.CreateRelationship(driver)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
return
}
c.JSON(http.StatusCreated, gin.H{"relationship": rec.AsMap()})
}
}

View File

@@ -0,0 +1,32 @@
package handlers
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
)
func CreateRelationshipAndPerson(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
var rp memgraph.RelationshipAndPerson
if err := c.ShouldBindJSON(&rp); err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
rec, err := rp.CreateRelationshipAndPerson(driver)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
return
}
c.JSON(http.StatusCreated, gin.H{"relationship": rec.AsMap()})
}
}

View File

@@ -0,0 +1,48 @@
package handlers
import (
"encoding/json"
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
)
func DeletePerson(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
if c.Request.Body == nil || c.ContentType() != "application/json" {
log.Printf("ip: %s error: request body is empty or content type is not application/json", c.ClientIP())
c.JSON(http.StatusBadRequest, gin.H{"error": "content type must be application/json and request body must not be empty"})
return
}
var person memgraph.Person
err := json.NewDecoder(c.Request.Body).Decode(&person)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
return
}
if person.ID != "" {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": "no person ID provided"})
return
}
err = person.DeletePerson(driver)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusNotFound, gin.H{"error": "could not delete person with ID provided"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "person deleted successfully"})
}
}

View File

@@ -0,0 +1,32 @@
package handlers
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
)
func DeleteRelationship(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
var relationship memgraph.Relationship
if err := c.ShouldBindJSON(&relationship); err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err := relationship.DeleteRelationship(driver)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
return
}
c.JSON(http.StatusAccepted, gin.H{"status": "relationship deleted successfully"})
}
}

View File

@@ -0,0 +1,48 @@
package handlers
import (
"encoding/json"
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
)
func UpdatePerson(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
if c.Request.Body == nil || c.ContentType() != "application/json" {
log.Printf("ip: %s error: request body is empty or content type is not application/json", c.ClientIP())
c.JSON(http.StatusBadRequest, gin.H{"error": "content type must be application/json and request body must not be empty"})
return
}
var person memgraph.Person
err := json.NewDecoder(c.Request.Body).Decode(&person)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request body"})
return
}
if person.ID == "" {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": "No ID provided"})
return
}
rec, err := person.UpdatePerson(driver)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusNotFound, gin.H{"error": "could not update person with information provided"})
return
}
c.JSON(http.StatusOK, gin.H{"person": rec.AsMap()})
}
}

View File

@@ -0,0 +1,32 @@
package handlers
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
)
func VerifyRelationship(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
var relationship memgraph.Relationship
if err := c.ShouldBindJSON(&relationship); err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
rec, err := relationship.VerifyRelationship(driver)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
return
}
c.JSON(http.StatusOK, gin.H{"relationship": rec.AsMap()})
}
}

View File

@@ -0,0 +1,55 @@
package handlers
import (
"context"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
)
func ViewFamiliyTree(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
session := driver.NewSession(ctx, neo4j.SessionConfig{AccessMode: neo4j.AccessModeRead})
defer session.Close(ctx)
id := c.GetString("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "id is required"})
return
}
query := `
MATCH (n:Person {id: $person_id})-[p:Parent*1..]->(family:Person)
OPTIONAL MATCH (family)-[c:Child]->(children:Person)
WITH family, p, children, c, n
OPTIONAL MATCH (children)<-[p2:Parent]-(OtherParents:Person)
WITH family, p, children, c, OtherParents, p2,n
OPTIONAL MATCH (family)-[s:Spouse]-(spouse:Person)
RETURN family, p, children, c, OtherParents, p2, spouse, s, n;`
result, err := session.Run(ctx, query, map[string]any{"person_id": id})
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
return
}
rec, err := result.Collect(ctx)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusNotFound, gin.H{"error": "could not find family tree for person with id: " + id})
return
}
c.JSON(200, rec)
}
}

View File

@@ -0,0 +1,50 @@
package handlers
import (
"context"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
)
func ViewPerson(driver neo4j.DriverWithContext) gin.HandlerFunc {
return func(c *gin.Context) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
session := driver.NewSession(ctx, neo4j.SessionConfig{AccessMode: neo4j.AccessModeRead})
defer session.Close(ctx)
id := c.Query("id")
if id == "" {
id = c.GetString("id")
}
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "id is required"})
return
}
result, err := session.Run(ctx, "MATCH (n:Person) WHERE n.id = $person_id RETURN n;", map[string]any{"person_id": id})
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
return
}
rec, err := result.Single(ctx)
if err != nil {
log.Printf("ip: %s error: %s", c.ClientIP(), err)
c.JSON(http.StatusNotFound, gin.H{"error": "could not find person with information provided"})
return
}
c.JSON(200, rec.AsMap()["n"])
}
}

106
cmd/backend/main.go Normal file
View File

@@ -0,0 +1,106 @@
package main
import (
"context"
"flag"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/vcscsvcscs/GenerationsHeritage/cmd/backend/handlers"
utilities "github.com/vcscsvcscs/GenerationsHeritage/pkg"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/gin/healthcheck"
"github.com/vcscsvcscs/GenerationsHeritage/pkg/memgraph"
//"github.com/zitadel/zitadel-go/v3/pkg/authorization"
//"github.com/zitadel/zitadel-go/v3/pkg/authorization/oauth"
//"github.com/zitadel/zitadel-go/v3/pkg/zitadel"
)
var (
cert = flag.String("cert", "/etc/gh-backend/ssl/tls.crt", "Specify the path of TLS cert")
key = flag.String("key", "/etc/gh-backend/ssl/tls.key", "Specify the path of TLS key")
httpsPort = flag.String("https", ":443", "Specify port for http secure hosting(example for format :443)")
httpPort = flag.String("http", ":80", "Specify port for http hosting(example for format :80)")
// zitadelAccessKey = flag.String("zitadel-access-key", "/etc/gh-backend/zitadel/api-key.json", "Specify the path of Zitadel access key")
// zitadelURI = flag.String("zitadel-uri", "zitadel.varghacsongor.hu", "Specify the Zitadel URI")
memgraphURI = flag.String("memgraph", "bolt+ssc://memgraph:7687", "Specify the Memgraph database URI")
memgraphUser = flag.String("memgraph-user", "", "Specify the Memgraph database user")
memgraphPass = flag.String("memgraph-pass", "", "Specify the Memgraph database password")
release = flag.Bool("release", false, "Set true to release build")
logToFile = flag.Bool("log-to-file", false, "Set true to log to file")
logToFileAndStd = flag.Bool("log-to-file-and-std", false, "Set true to log to file and std")
requestTimeout = time.Duration(*flag.Int("request-timeout", 20, "Set request timeout in seconds"))
)
func main() {
flag.Parse()
if *release {
gin.SetMode(gin.ReleaseMode)
}
utilities.SetupLogger(*logToFileAndStd, *logToFile)
hc := healthcheck.New()
memgraphDriver := memgraph.InitDatabase(*memgraphURI, *memgraphUser, *memgraphPass)
router := gin.Default()
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:5173", "http://localhost", "https://heritagebackend.varghacsongor.hu", "https://feature-add-frontend.generationsheritage.pages.dev/", "https://csalad.varghacsongor.hu/"},
AllowCredentials: true,
AllowHeaders: []string{"Authorization", "id", "Content-Type"},
MaxAge: 12 * time.Hour,
}))
router.Use(gin.Recovery())
//ctx := context.Background()
// Initiate the authorization by providing a zitadel configuration and a verifier.
// This example will use OAuth2 Introspection for this, therefore you will also need to provide the downloaded api key.json
//authZ, err := authorization.New(ctx, zitadel.New(*zitadelURI), oauth.DefaultAuthorization(*zitadelAccessKey))
//if err != nil {
// log.Println("zitadel sdk could not initialize", "error", err)
// os.Exit(1)
//}
// Initialize the HTTP middleware by providing the authorization
//mw := middleware.New(authZ)
//router.Use(auth(mw))
router.GET("/health", hc.HealthCheckHandler())
router.GET("/person", handlers.ViewPerson(memgraphDriver))
router.POST("/person", handlers.CreatePerson(memgraphDriver))
router.DELETE("/person", handlers.DeletePerson(memgraphDriver))
router.PUT("/person", handlers.UpdatePerson(memgraphDriver))
router.POST("/relationship", handlers.CreateRelationship(memgraphDriver))
router.DELETE("/relationship", handlers.DeleteRelationship(memgraphDriver))
router.PUT("/relationship", handlers.VerifyRelationship(memgraphDriver))
router.POST("/createRelationshipAndPerson", handlers.CreateRelationshipAndPerson(memgraphDriver))
router.GET("/familyTree", handlers.ViewFamiliyTree(memgraphDriver))
server := utilities.SetupHttpsServer(router, *cert, *key, *httpsPort, *httpPort, requestTimeout)
// Wait for interrupt signal to gracefully shutdown the server with some time to finish requests.
quit := make(chan os.Signal, 1)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be caught, so don't need to add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-quit
log.Println("Shutting down server...")
// The context is used to inform the server it has some seconds to finish
// the request it is currently handling
ctx, cancel := context.WithTimeout(context.Background(), requestTimeout*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
log.Fatal("Server forced to shutdown:", err)
}
log.Println("Server exiting")
}

File diff suppressed because it is too large Load Diff

View File

@@ -16,16 +16,23 @@
"@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"autoprefixer": "^10.4.19",
"daisyui": "^4.10.2",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-svelte": "^2.35.1",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.2",
"svelte": "^4.2.12",
"tailwindcss": "^3.4.3",
"vite": "^5.0.3"
},
"type": "module",
"dependencies": {
"@dagrejs/dagre": "github:dagrejs/dagre",
"@xyflow/svelte": "^0.0.41",
"oidc-client-ts": "^3.0.1",
"svelte-eslint-parser": "^0.33.1"
}
}

View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {}
}
};

79
cmd/frontend/src/app.html Normal file
View File

@@ -0,0 +1,79 @@
<!doctype html>
<html lang="en" style="width: 100%; height: 100%">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover" style="width: 100vw; height: 100vh">
<div style="display: contents; width: 100vw; height: 100vh" class="bg-base-100">
%sveltekit.body%
</div>
<div
class="dropdown mb-72"
style="position: absolute; left: auto; right: 3vw; top: 10px; bottom: auto"
>
<div tabindex="0" role="button" class="btn m-1">
Theme
<svg
width="12px"
height="12px"
class="h-2 w-2 fill-current opacity-60 inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 2048 2048"
>
<path d="M1799 349l242 241-1017 1017L7 590l242-241 775 775 775-775z"></path>
</svg>
</div>
<ul tabindex="0" class="dropdown-content z-[1] p-2 shadow-2xl bg-base-300 rounded-box w-36">
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Light"
value="light"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Dark"
value="dark"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Cyberpunk"
value="cyberpunk"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Synthwave"
value="synthwave"
/>
</li>
<li>
<input
type="radio"
name="theme-dropdown"
class="theme-controller btn btn-sm btn-block btn-ghost justify-start"
aria-label="Retro"
value="retro"
/>
</li>
</ul>
</div>
</body>
</html>

View File

@@ -0,0 +1,66 @@
import { UserManager, WebStorageStateStore, type User } from 'oidc-client-ts';
import { isAuthenticated, user } from './stores';
import { PUBLIC_ZITADEL_CLIENT_ID, PUBLIC_ISSUER } from '$env/static/public';
import { goto } from '$app/navigation';
import { browser } from '$app/environment';
let userManager: UserManager;
if (browser) {
const host_url = window.location.href.startsWith('http://')
? 'http://localhost:5173'
: 'https://' + window.location.hostname;
const config = {
authority: PUBLIC_ISSUER, // At Zitadel Project Console > [Your project] > [Your application] > URLs - Issuer
client_id: PUBLIC_ZITADEL_CLIENT_ID, // At Zitadel Project Console > [Your project] > [Your application] > Configuration - Client ID
redirect_uri: host_url + '/callback', // At Zitadel Project Console > [Your project] > [Your application] > URLs - Login Redirect URI
response_type: 'code',
scope: 'openid profile email',
post_logout_redirect_uri: host_url,
userStore: new WebStorageStateStore({ store: window.localStorage }),
automaticSilentRenew: true,
silent_redirect_uri: host_url + '/silent-refresh'
};
userManager = new UserManager(config);
userManager.events.addUserLoaded((loadedUser: User) => {
console.log('userManager.events.addUserLoaded');
user.set(loadedUser);
isAuthenticated.set(true);
});
userManager.events.addUserUnloaded(() => {
console.log('userManager.events.addUserUnloaded');
user.set(null);
isAuthenticated.set(false);
});
}
async function login(): Promise<void> {
console.log('UserManager.login()');
if (browser) {
await userManager.signinRedirect();
}
}
async function logout(): Promise<void> {
if (browser) {
await userManager.signoutRedirect();
}
}
async function handleCallback(): Promise<void> {
if (browser) {
await userManager.signinRedirectCallback();
goto('/');
}
}
async function handleSilentCallback(): Promise<void> {
if (browser) {
await userManager.signinSilentCallback();
goto('/');
}
}
export { login, logout, handleCallback, handleSilentCallback };

View File

@@ -0,0 +1,215 @@
<script lang="ts">
import { PUBLIC_API_URL } from '$env/static/public';
import { setFamilyTreeNodes } from './setFamilyTreeNodes';
import { user } from '../stores';
import { onMount } from 'svelte';
export let id = '';
let auth_token = '';
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
let relationship = '';
let dialog: HTMLDialogElement;
let payload = {
relationship: {
first_person_id: id,
relationship: relationship,
direction: '->'
},
person: {
first_name: '',
middle_name: '',
last_name: '',
mothers_first_name: '',
mothers_last_name: '',
born: '',
birthplace: '',
titles: [],
residence: '',
death: '',
deathplace: '',
life_events: [],
occupation: [],
occupation_to_display: '',
others_said: {},
photos: {},
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
}
};
function handleSubmit(event: Event) {
event.preventDefault();
if (
id &&
relationship &&
payload.person.first_name &&
payload.person.last_name &&
payload.person.born &&
payload.person.mothers_first_name &&
payload.person.mothers_last_name
) {
fetch(PUBLIC_API_URL + '/createRelationshipAndPerson', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: auth_token
},
body: JSON.stringify(payload)
}).then((response) => {
if (response.ok) {
setFamilyTreeNodes();
dialog.close();
} else {
alert('Failed to add family member! with status ' + response.status);
}
});
} else {
alert('You have to fill out all the required fields!');
}
}
onMount(() => {
if (dialog) dialog.showModal();
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<h1 class="font-bold text-lg">Create a family members profile</h1>
<p>
You can add a family member to your family tree by filling out the form below. You can update
the information later.
</p>
<form on:submit={handleSubmit} method="dialog" class="flex flex-col gap-4">
<div class="grid grid-cols-2 gap-4">
<label for="relationship" class="input input-bordered flex items-center gap-2">
Relationship type:
<select id="relationship" bind:value={relationship} required>
<option value="" disabled selected>Choose one ...</option>
<option value="Parent">Parent</option>
<option value="Child">Child</option>
<option value="Spouse">Spouse</option>
<option value="Sibling">Sibling</option>
</select>
</label>
<label for="firstName" class="input input-bordered flex items-center gap-2">
First Name:
<input
type="text"
id="firstName"
class="grow input-md"
bind:value={payload.person.first_name}
required
/>
</label>
<label for="middleName" class="input input-bordered flex items-center gap-2">
Middle Name:
<input
type="text"
id="middleName"
class="grow input-md"
bind:value={payload.person.middle_name}
/>
</label>
<label for="lastName" class="input input-bordered flex items-center gap-2">
Last Name:
<input
type="text"
id="lastName"
class="grow input-md"
bind:value={payload.person.last_name}
required
/>
</label>
<label for="born" class="input input-bordered flex items-center gap-2">
Born:
<input
type="date"
id="born"
class="grow input-md"
bind:value={payload.person.born}
required
/>
</label>
<label for="birthplace" class="input input-bordered flex items-center gap-2">
Birthplace:
<input
type="text"
id="birthplace"
class="grow input-md"
bind:value={payload.person.birthplace}
required
/>
</label>
<label for="mothersFirstName" class="input input-bordered flex items-center gap-2">
Mother's First Name:
<input
type="text"
id="mothersFirstName"
class="grow input-md"
bind:value={payload.person.mothers_first_name}
required
/>
</label>
<label for="mothersLastName" class="input input-bordered flex items-center gap-2">
Mother's Last Name:
<input
type="text"
id="mothersLastName"
class="grow input-md"
bind:value={payload.person.mothers_last_name}
required
/>
</label>
<label for="death" class="input input-bordered flex items-center gap-2">
Death:
<input type="date" id="death" class="grow input-md" bind:value={payload.person.death} />
</label>
<label for="deathplace" class="input input-bordered flex items-center gap-2">
Place of death:
<input
type="text"
id="deathplace"
class="grow input-md"
bind:value={payload.person.deathplace}
/>
</label>
<label for="residence" class="input input-bordered flex items-center gap-2">
Residence:
<input
type="text"
id="residence"
class="grow input-md"
bind:value={payload.person.residence}
/>
</label>
<label for="titles" class="input input-bordered flex items-center gap-2">
Titles:
<input type="text" id="titles" class="grow input-md" bind:value={payload.person.titles} />
</label>
</div>
<button type="submit" class="btn btn-primary w-40 place-self-end">Add</button>
</form>
</div>
</dialog>

View File

@@ -0,0 +1,80 @@
<script lang="ts">
import { PUBLIC_API_URL } from '$env/static/public';
import { setFamilyTreeNodes } from './setFamilyTreeNodes';
import { user } from '$lib/stores';
import { onMount } from 'svelte';
export let id = '';
let relationship = '';
let second_person_id = '';
let dialog: HTMLDialogElement; // HTMLDialogElement
let auth_token = '';
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
function handleSubmit(event: SubmitEvent) {
event.preventDefault();
if (second_person_id && id && relationship) {
const payload = {
first_person_id: id,
second_person_id: second_person_id,
relationship: relationship,
direction: '->'
};
fetch(PUBLIC_API_URL + '/relationship', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: auth_token
},
body: JSON.stringify(payload)
}).then((response) => {
if (response.ok) {
setFamilyTreeNodes();
dialog.close();
} else {
alert('Failed to add relationship! with status ' + response.status);
}
});
} else {
alert('You have to fill out all the fields!');
}
}
onMount(() => {
if (dialog) dialog.showModal();
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<h1 class="font-bold text-lg">Add a relationship</h1>
<p>
Ask your relative to give you their id and set what kind of relationship you have with them.
</p>
<form on:submit={handleSubmit} method="dialog">
<label for="id" class="input input-bordered flex items-center gap-2">
ID:
<input type="text" id="id" class="grow" bind:value={id} required />
</label>
<label for="relationship">Relationship type:</label>
<select id="relationship" bind:value={relationship} required>
<option value="" disabled selected>Choose one ...</option>
<option value="Parent">Parent</option>
<option value="Child">Child</option>
<option value="Spouse">Spouse</option>
<option value="Sibling">Sibling</option>
</select>
<button type="submit" class="btn btn-primary">Add</button>
</form>
</div>
</dialog>

View File

@@ -0,0 +1,152 @@
<script lang="ts">
import { PUBLIC_API_URL } from '$env/static/public';
import { onMount } from 'svelte';
import { user } from '../stores';
let auth_token = '';
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
let dialog: HTMLDialogElement;
let payload = {
first_name: '',
middle_name: '',
last_name: '',
mothers_first_name: '',
mothers_last_name: '',
born: '',
birthplace: '',
titles: [],
residence: '',
life_events: [],
occupation: [],
occupation_to_display: '',
photos: {},
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
};
function handleSubmit(event: Event) {
event.preventDefault();
if (
payload.first_name &&
payload.last_name &&
payload.born &&
payload.mothers_first_name &&
payload.mothers_last_name
) {
payload.born = new Date(payload.born).toISOString();
fetch(PUBLIC_API_URL + '/person', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer' + auth_token
},
body: JSON.stringify(payload)
}).then((response) => {
if (response.ok) {
dialog.close();
} else {
alert('Failed to create profile! with status ' + response.status);
}
});
} else {
alert('You have to fill out all the required fields!');
}
}
onMount(() => {
if (dialog) dialog.showModal();
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl flex flex-col gap-4">
<h1 class="font-bold text-lg">Create your profile</h1>
<p>To start building your family tree fill this form. You can add more information later.</p>
<form on:submit={handleSubmit} method="dialog">
<div class="grid grid-cols-2 gap-4">
<label class="input input-bordered flex items-center gap-2" for="firstName">
First Name:
<input
type="text"
id="firstName"
class="grow input-md"
bind:value={payload.first_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="middleName">
Middle Name:
<input
type="text"
id="middleName"
class="grow input-md"
bind:value={payload.middle_name}
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="lastName">
Last Name:
<input
type="text"
id="lastName"
class="grow input-md"
bind:value={payload.last_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="born">
Born:
<input type="date" id="born" class="grow input-md" bind:value={payload.born} required />
</label>
<label class="input input-bordered flex items-center gap-2" for="birthplace">
Birthplace:
<input
type="text"
id="birthplace"
class="grow input-md"
bind:value={payload.birthplace}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="mothersFirstName">
Mother's First Name:
<input
type="text"
id="mothersFirstName"
class="grow input-md"
bind:value={payload.mothers_first_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="mothersLastName">
Mother's Last Name:
<input
type="text"
id="mothersLastName"
class="grow input-md"
bind:value={payload.mothers_last_name}
required
/>
</label>
<label class="input input-bordered flex items-center gap-2" for="residence">
Residence:
<input type="text" id="residence" class="grow input-md" bind:value={payload.residence} />
</label>
<label class="input input-bordered flex items-center gap-2" for="titles">
Titles:
<input type="text" id="titles" class="grow input-md" bind:value={payload.titles} />
</label>
<button type="submit" class="btn btn-primary w-40 place-self-end">Add</button>
</div>
</form>
</div>
</dialog>

View File

@@ -0,0 +1,61 @@
<script lang="ts">
import { onMount } from 'svelte';
export let onClick: () => void;
export let deleteNode: () => void;
export let addRelationship: () => void;
export let addFamilymember: () => void;
export let id: string;
export let top: number | undefined;
export let left: number | undefined;
export let right: number | undefined;
export let bottom: number | undefined;
let contextMenu: HTMLDivElement;
onMount(() => {
if (top) {
contextMenu.style.top = `${top}px`;
}
if (left) {
contextMenu.style.left = `${left}px`;
}
if (right) {
contextMenu.style.right = `${right}px`;
}
if (bottom) {
contextMenu.style.bottom = `${bottom}px`;
}
});
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
bind:this={contextMenu}
class="context-menu bg-primary-100 rounded-lg shadow-lg"
on:click={onClick}
>
<p style="margin: 0.5em;">
<small>node: {id}</small>
</p>
<button on:click={addRelationship} class="btn">Add Relationship</button>
<button on:click={addFamilymember} class="btn">Add familymember</button>
<button on:click={deleteNode} class="btn">Delete</button>
</div>
<style>
.context-menu {
border-style: solid;
box-shadow: 10px 19px 20px rgba(0, 0, 0, 10%);
position: absolute;
z-index: 10;
}
.context-menu button {
border: none;
display: block;
padding: 0.5em;
text-align: left;
width: 100%;
}
</style>

View File

@@ -0,0 +1,70 @@
<script lang="ts">
import { Handle, Position, type NodeProps } from '@xyflow/svelte';
export let id: NodeProps['id'];
id;
export let dragHandle: NodeProps['dragHandle'] = undefined;
dragHandle;
export let type: NodeProps['type'] = undefined;
type;
export let selected: NodeProps['selected'] = undefined;
selected;
export let width: NodeProps['width'] = undefined;
width;
export let height: NodeProps['height'] = undefined;
height;
export let dragging: NodeProps['dragging'];
dragging;
export let targetPosition: NodeProps['targetPosition'] = undefined;
targetPosition;
export let sourcePosition: NodeProps['sourcePosition'] = undefined;
sourcePosition;
export let data = {
id: '',
last_name: 'Nem',
first_name: 'Ismert',
middle_name: '',
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
};
</script>
<div class="rounded-badge card card-compact bg-base-300">
<div class="card-body items-center text-center w-30">
<div class="avatar">
<figure class="w-24 mask mask-squircle">
<img src={'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'} alt="Picture of {data.last_name} {data.first_name}" />
</figure>
</div>
<h2 class="card-title text-base-content">
{data.first_name}
{data.middle_name ? data.middle_name : ''}
{data.last_name}
</h2>
</div>
</div>
<Handle
type="target"
position={Position.Top}
id="spouse"
style="transform: translate(10px, 50%); left: 0;"
/>
<Handle
type="source"
position={Position.Top}
id="spouse"
style="transform: translate(0, 50%); left: auto; right: 10px"
/>
<Handle type="target" position={Position.Top} id="parent" style="transform: translate(0, 50%);" />
<Handle
type="source"
position={Position.Bottom}
id="child"
style="transform: translate(0, -3px);"
/>
<Handle type="target" position={Position.Top} id="child" style="transform: translate(0, 50%);" />
<Handle
type="source"
position={Position.Bottom}
id="parent"
style="transform: translate(0, -3px);"
/>

View File

@@ -0,0 +1,53 @@
<script lang="ts">
import { onMount } from 'svelte';
import { fetch_profile } from './getProfile';
export let data = {
id: '',
last_name: 'Nem',
first_name: 'Ismert',
middle_name: '',
profile_picture: 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png'
};
let dialog: HTMLDialogElement; // HTMLDialogElement
onMount(() => {
if (dialog) dialog.showModal();
fetch_profile(data.id).then((data) => {
data = data
});
data.profile_picture = 'https://cdn-icons-png.flaticon.com/512/3607/3607444.png';
});
</script>
<dialog bind:this={dialog} class="modal bg-base-300">
<div class="modal-box w-11/12 max-w-5xl">
<form method="dialog">
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"></button>
</form>
<div class="hero min-h-screen bg-base-200">
<div class="hero-content flex-col lg:flex-row">
<div class="avatar max-w-sm rounded-lg shadow-2xl">
<figure class="w-24 mask mask-squircle">
<img src={data.profile_picture} alt="Picture of {data.last_name} {data.first_name}" />
</figure>
</div>
<div>
<h1 class="text-5xl font-bold">
{data.first_name}
{data.middle_name ? data.middle_name : ''}
{data.last_name}
</h1>
<p class="py-6">
Provident cupiditate voluptatem et in. Quaerat fugiat ut assumenda excepturi
exercitationem quasi. In deleniti eaque aut repudiandae et a id nisi.
</p>
</div>
</div>
</div>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
</div>
</dialog>

View File

@@ -0,0 +1,39 @@
import dagre from '@dagrejs/dagre';
import { Position, type Node, type Edge } from '@xyflow/svelte';
const dagreGraph = new dagre.graphlib.Graph();
const nodeWidth = 250;
const nodeHeight = 250;
function getLayoutedElements(nodes: Node[], edges: Edge[], direction = 'TB') {
dagreGraph.setDefaultEdgeLabel(() => ({}));
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({ rankdir: direction });
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});
edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});
dagre.layout(dagreGraph);
nodes.forEach((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
node.targetPosition = isHorizontal ? Position.Left : Position.Top;
node.sourcePosition = isHorizontal ? Position.Right : Position.Bottom;
// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
node.position = {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2
};
});
return { nodes, edges };
}
export { getLayoutedElements };

View File

@@ -0,0 +1,77 @@
import { type Node, type Edge } from '@xyflow/svelte';
function AddToNodesData(data: any, i: number, pushToNodesCallback: (arg: Node) => void) {
if (data[0].Values[i] != null) {
if (Object.prototype.toString.call(data[0].Values[i]) === '[object Array]') {
data[0].Values[i].forEach((person: { ElementId: string; Props: {} }) => {
pushToNodesCallback({
id: person.ElementId,
type: 'custom',
data: person.Props,
position: { x: 0, y: 0 }
});
});
} else {
console.log(data[0].Values[i]);
pushToNodesCallback({
id: data[0].Values[i].ElementId,
type: 'custom',
data: data[0].Values[i].Props,
position: { x: 0, y: 0 }
});
}
}
}
function AddToEdgesData(data: any, i: number, pushToEdgesCallback: (arg: Edge) => void) {
if (data[0].Values[i] != null) {
if (Object.prototype.toString.call(data[0].Values[i]) === '[object Array]') {
data[0].Values[i].forEach(
(edge: {
ElementId: string;
StartElementId: string;
EndElementId: string;
Type: string;
Props: {};
}) => {
pushToEdgesCallback({
id: edge.ElementId,
source: edge.StartElementId,
sourceHandle:
edge.Type === 'Parent' ? 'parent' : edge.Type === 'Child' ? 'child' : 'spouse',
target: edge.EndElementId,
targetHandle:
edge.Type === 'Parent' ? 'child' : edge.Type === 'Child' ? 'parent' : 'spouse',
label: edge.Type,
data: edge.Props,
zIndex: edge.Type === 'Spouse' ? 1 : 0
});
}
);
} else {
console.log(data[0].Values[i]);
pushToEdgesCallback({
id: data[0].Values[i].ElementId,
source: data[0].Values[i].StartElementId,
sourceHandle:
data[0].Values[i].Type === 'Parent'
? 'parent'
: data[0].Values[i].Type === 'Child'
? 'child'
: 'spouse',
target: data[0].Values[i].EndElementId,
targetHandle:
data[0].Values[i].Type === 'Parent'
? 'child'
: data[0].Values[i].Type === 'Child'
? 'parent'
: 'spouse',
label: data[0].Values[i].Type,
data: data[0].Values[i].Props,
zIndex: data[0].Values[i].Type === 'Spouse' ? 1 : 0
});
}
}
}
export { AddToNodesData, AddToEdgesData };

View File

@@ -0,0 +1,24 @@
import { PUBLIC_API_URL } from '$env/static/public';
import { user } from '$lib/stores';
let auth_token: string;
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
async function fetch_family_tree() {
const response = await fetch(PUBLIC_API_URL + '/familyTree', {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + auth_token
}
});
const data = await response.json();
return data;
}
export { fetch_family_tree };

View File

@@ -0,0 +1,24 @@
import { PUBLIC_API_URL } from '$env/static/public';
import { user } from '$lib/stores';
let auth_token: string;
user.subscribe((value) => {
if (value) {
auth_token = value.access_token;
}
});
async function fetch_profile(id: string = '') {
const response = await fetch(PUBLIC_API_URL + '/person' + (id != '' ? '?id=' + id : ''), {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: 'Bearer ' + auth_token
}
});
const data = await response.json();
return data;
}
export { fetch_profile };

View File

@@ -0,0 +1,61 @@
import { fetch_family_tree } from '$lib/family_tree/getFamilyTree';
import { getLayoutedElements } from '$lib/family_tree/dagreLayout';
import { AddToNodesData, AddToEdgesData } from '$lib/family_tree/dataAdapter';
import type { Node, Edge } from '@xyflow/svelte';
import { useEdges, useNodes } from '@xyflow/svelte';
import { fetch_profile } from './getProfile';
export async function setFamilyTreeNodes(): Promise<{
nodes: Node[];
edges: Edge[];
}> {
console.log('fetching nodes');
let layoutedElements: {
nodes: Node[];
edges: Edge[];
} = { nodes: [], edges: [] };
let nodes_data: Node[] = [];
let edges_data: Edge[] = [];
await fetch_profile().then((data) => {
nodes_data.push({
id: data.ElementId,
type: 'custom',
data: data.Props,
position: { x: 0, y: 0 }
});
});
await fetch_family_tree().then((data: []) => {
if (data.length == 0) {
return layoutedElements;
}
function pushNodeToData(node: Node) {
nodes_data.push(node);
}
AddToNodesData(data, 0, pushNodeToData);
AddToNodesData(data, 2, pushNodeToData);
AddToNodesData(data, 4, pushNodeToData);
AddToNodesData(data, 6, pushNodeToData);
AddToNodesData(data, 8, pushNodeToData);
function pushEdgeToData(edge: Edge) {
edges_data.push(edge);
}
AddToEdgesData(data, 1, pushEdgeToData);
AddToEdgesData(data, 3, pushEdgeToData);
AddToEdgesData(data, 5, pushEdgeToData);
AddToEdgesData(data, 7, pushEdgeToData);
});
console.log('Fetched nodes and edges data.');
// Remove duplicate nodes
nodes_data = nodes_data.filter(
(node, index, self) => index === self.findIndex((n) => n.id === node.id)
);
return getLayoutedElements(nodes_data, edges_data, 'TB');
}

View File

@@ -0,0 +1,5 @@
import { writable } from 'svelte/store';
import type { User } from 'oidc-client-ts';
export const isAuthenticated = writable<boolean>(false);
export const user = writable<User | null>(null);

View File

@@ -0,0 +1,3 @@
export const prerender = true;
import 'tailwindcss/tailwind.css';
import '@xyflow/svelte/dist/style.css';

View File

@@ -0,0 +1,139 @@
<script lang="ts">
import { writable } from 'svelte/store';
import { onMount } from 'svelte';
import { SvelteFlowProvider, SvelteFlow, Controls, MiniMap } from '@xyflow/svelte';
import type { Node, Edge, NodeTypes } from '@xyflow/svelte';
import { isAuthenticated } from '../lib/stores';
import PersonNode from './../lib/family_tree/PersonNode.svelte';
import { setFamilyTreeNodes } from '../lib/family_tree/setFamilyTreeNodes';
import { login } from '../lib/auth';
import PersonMenu from '$lib/family_tree/PersonMenu.svelte';
import PersonPanel from '$lib/family_tree/PersonPanel.svelte';
import AddRelationship from '$lib/family_tree/AddRelationship.svelte';
import AddFamilyMember from '$lib/family_tree/AddFamilyMember.svelte';
import CreateProfile from '$lib/family_tree/CreateProfile.svelte';
let relationshipPanel = '';
let AddFamilyMemberPanel = '';
let CreateProfilePanel = false;
const nodes = writable<Node[]>([]);
const edges = writable<Edge[]>([]);
onMount(() => {
if (!$isAuthenticated) {
console.log('user is not authenticated');
login();
} else {
console.log('user is authenticated');
setFamilyTreeNodes().then((layout) => {
if (layout.nodes.length < 1) {
CreateProfilePanel = true;
} else {
nodes.set(layout.nodes);
edges.set(layout.edges);
}
});
}
});
const nodeTypes: NodeTypes = {
custom: PersonNode
};
let personPanel:
| {
id: string;
last_name: string;
first_name: string;
middle_name: string;
profile_picture: string;
}
| undefined;
let menu: { id: string; top?: number; left?: number; right?: number; bottom?: number } | null;
let width: number;
let height: number;
function handleContextMenu({
detail: { event, node }
}: {
detail: { event: MouseEvent; node: Node };
}) {
event.preventDefault();
menu = {
id: node.data.id,
top: event.clientY < height - 200 ? event.clientY : undefined,
left: event.clientX < width - 200 ? event.clientX : undefined,
right: event.clientX >= width - 200 ? width - event.clientX : undefined,
bottom: event.clientY >= height - 200 ? height - event.clientY : undefined
};
}
// Close the context menu if it's open whenever the window is clicked.
function handlePaneClick() {
menu = null;
relationshipPanel = '';
}
function handleNodeClick({
detail: { event, node }
}: {
detail: { event: MouseEvent; node: Node };
}) {
event.preventDefault();
personPanel = node.data;
}
</script>
<div style="height:100vh;">
<SvelteFlowProvider>
<SvelteFlow
{nodes}
{nodeTypes}
{edges}
on:nodecontextmenu={handleContextMenu}
on:nodeclick={handleNodeClick}
on:paneclick={handlePaneClick}
class="bg-base-100"
fitView
onlyRenderVisibleElements
>
<Controls class="bg-base-300 text-base-content" />
<MiniMap class="bg-base-200" />
{#if menu != null}
<PersonMenu
onClick={handlePaneClick}
deleteNode={() => {
console.log('delete node');
}}
addRelationship={() => {
if (menu) relationshipPanel = menu.id;
}}
addFamilymember={() => {
if (menu) AddFamilyMemberPanel = menu.id;
}}
id={menu.id}
top={menu.top}
left={menu.left}
right={menu.right}
bottom={menu.bottom}
/>
{/if}
{#if personPanel != null}
<PersonPanel data={personPanel} />
{/if}
{#if relationshipPanel != ''}
<AddRelationship id={relationshipPanel} />
{/if}
{#if AddFamilyMemberPanel != ''}
<AddFamilyMember id={AddFamilyMemberPanel} />
{/if}
{#if CreateProfilePanel}
<CreateProfile />
{/if}
</SvelteFlow>
</SvelteFlowProvider>
</div>

View File

@@ -0,0 +1,11 @@
<!-- src/routes/callback.svelte -->
<script lang="ts">
import { onMount } from 'svelte';
import { handleCallback } from '../../lib/auth';
onMount(() => {
handleCallback();
});
</script>
<div>Logging in...</div>

View File

@@ -0,0 +1,10 @@
<script lang="ts">
import { onMount } from 'svelte';
import { handleSilentCallback } from '../../lib/auth';
onMount(() => {
handleSilentCallback();
});
</script>
<div>Refreshing...</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

View File

@@ -1,7 +1,9 @@
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter({
pages: 'build',

View File

@@ -0,0 +1,12 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{html,svelte,js,ts}'],
important: true,
theme: {
extend: {}
},
daisyui: {
themes: ['light', 'dark', 'cyberpunk', 'synthwave', 'retro', 'roboto', 'dracula']
},
plugins: [require('daisyui')]
};

View File

@@ -0,0 +1,14 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
},
"include": ["src/**/*", "src/node_modules", ".svelte-kit/ambient.d.ts"] // see last element
}

View File

@@ -1,22 +0,0 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gh-auth-service
spec:
project: generations-heritage-vv
source:
repoURL: 'https://github.com/vcscsvcscs/GenerationsHeritage'
path: deployment/auth-service
targetRevision: main
kustomize:
namespace: generations-heritage
destination:
server: 'https://kubernetes.default.svc'
namespace: generations-heritage
syncPolicy:
automated:
selfHeal: true
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

View File

@@ -1,17 +0,0 @@
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/instance: gh-auth-service
app.kubernetes.io/name: gh-auth-service
name: gh-auth-service
spec:
ports:
- name: gin
port: 443
protocol: TCP
targetPort: 443
selector:
app.kubernetes.io/instance: gh-auth-service
app.kubernetes.io/name: gh-auth-service
type: ClusterIP

View File

@@ -0,0 +1,8 @@
rule.example_public.action=allow
rule.example_public.rule=Host("stats.example.com") && PathPrefix("/api/public")
rule.example_api.action=allow
rule.example_api.rule=Host("api.example.com") && Headers("X-API-Authorization", "a-long-api-key")
rule.example_api_query.action=allow
rule.example_api_query.rule=Host("api.example.com") && && Query("api_key=a-long-api-key")

View File

@@ -0,0 +1,78 @@
#
# Traefik Forward Auth Deployment
#
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik-forward-auth
labels:
app: traefik-forward-auth
spec:
replicas: 1
selector:
matchLabels:
app: traefik-forward-auth
strategy:
type: Recreate
template:
metadata:
labels:
app: traefik-forward-auth
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 60
containers:
- image: thomseddon/traefik-forward-auth:2
name: traefik-forward-auth
ports:
- containerPort: 4181
protocol: TCP
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
env:
- name: CONFIG
value: "/config"
- name: DOMAIN
value: "varghacsongor.hu"
# INSECURE_COOKIE is required if not using a https entrypoint
# - name: INSECURE_COOKIE
# value: "true"
# Remove COOKIE_DOMAIN if not using auth host mode
- name: COOKIE_DOMAIN
value: "example.com"
- name: AUTH_HOST
value: "auth.example.com"
- name: LOG_LEVEL
value: "info"
- name: PROVIDERS_GOOGLE_CLIENT_ID
valueFrom:
secretKeyRef:
name: traefik-forward-auth-secrets
key: google-client-id
- name: PROVIDERS_GOOGLE_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: traefik-forward-auth-secrets
key: google-client-secret
- name: SECRET
valueFrom:
secretKeyRef:
name: traefik-forward-auth-secrets
key: secret
volumeMounts:
- name: configs
mountPath: /configexample
subPath: traefik-forward-auth.ini
volumes:
- name: configs
configMap:
name: configs
- name: traefik-forward-auth-secrets
secret:
secretName: traefik-forward-auth-secrets

View File

@@ -0,0 +1,20 @@
#
# Auth Ingress
#
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-forward-auth
labels:
app: traefik
spec:
entryPoints:
- https
routes:
- match: Host(`auth.varghacsongor.hu`)
kind: Rule
services:
- name: traefik-forward-auth
port: 4181
tls:
certresolver: default

View File

@@ -0,0 +1,26 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: default
commonLabels:
app: traefik-forward-auth
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
- middleware.yaml
#
# Configs
#
configMapGenerator:
- name: configs
files:
- configs/traefik-forward-auth.ini
#
# Secrets
#
secretGenerator:
- name: traefik-forward-auth-secrets
env: secrets/traefik-forward-auth.env

View File

@@ -0,0 +1,9 @@
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: traefik-forward-auth
spec:
forwardAuth:
address: http://traefik-forward-auth:4181
authResponseHeaders:
- X-Forwarded-User

View File

@@ -0,0 +1,3 @@
google-client-id=client-id
google-client-secret=client-secret
secret=something-random

View File

@@ -0,0 +1,17 @@
#
# Auth Service
#
apiVersion: v1
kind: Service
metadata:
name: traefik-forward-auth
labels:
app: traefik
spec:
type: ClusterIP
selector:
app: traefik
ports:
- name: auth-http
port: 4181
targetPort: 4181

View File

@@ -1,7 +1,7 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: gh-auth-service-certificate
name: gh-authz-certificate
annotations:
argocd.argoproj.io/hook: PreSync
spec:
@@ -9,15 +9,15 @@ spec:
duration: 2160h # 90d
renewBefore: 360h # 15d
dnsNames:
- gh-auth-service.generations-heritage.svc.cluster.local
- gh-auth-service
- gh-authz.generations-heritage.svc.cluster.local
- gh-authz
- localhost
ipAddresses:
- 127.0.0.1
subject:
organizations:
- GenerationsHeritage
secretName: gh-auth-service-tls
secretName: gh-authz-tls
privateKey:
algorithm: RSA
encoding: PKCS1

View File

@@ -2,29 +2,29 @@ apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/instance: gh-auth-service
app.kubernetes.io/name: gh-auth-service
app.kubernetes.io/instance: gh-authz
app.kubernetes.io/name: gh-authz
annotations:
argocd.argoproj.io/sync-wave: "1"
argocd.argoproj.io/hook: Synce
name: gh-auth-service
name: gh-authz
namespace: generations-heritage
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: gh-auth-service
app.kubernetes.io/name: gh-auth-service
app.kubernetes.io/instance: gh-authz
app.kubernetes.io/name: gh-authz
template:
metadata:
labels:
app.kubernetes.io/instance: gh-auth-service
app.kubernetes.io/name: gh-auth-service
app.kubernetes.io/instance: gh-authz
app.kubernetes.io/name: gh-authz
spec:
containers:
- image: vcscsvcscs/gheritage-auth-service:latest
imagePullPolicy: Always
name: gh-auth-service
name: gh-authz
ports:
- containerPort: 443
name: gin
@@ -38,9 +38,14 @@ spec:
cpu: 100m
memory: 50Mi
volumeMounts:
- name: gh-auth-service-certs
mountPath: /etc/gh-auth-service/ssl
- name: gh-authz-certs
mountPath: /etc/gh-authz/ssl
- name: zitadel-service-account
mountPath: /etc/gh-authz/zitadel
volumes:
- name: gh-auth-service-certs
- name: gh-authz-certs
secret:
secretName: gh-auth-service-tls
secretName: gh-authz-tls
- name: zitadel-service-account
secret:
secretName: zitadel-service-account

View File

@@ -0,0 +1,11 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-service
spec:
forwardAuth:
address: https://gh-authz/auth/
authResponseHeaders:
- id
tls:
insecureSkipVerify: true

View File

@@ -1,14 +1,14 @@
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: gh-auth-service
name: gh-authz
annotations:
argocd.argoproj.io/hook: PostSync
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: gh-auth-service
name: gh-authz
minReplicas: 1
maxReplicas: 5
metrics:

View File

@@ -4,6 +4,8 @@ namespace: generations-heritage
resources:
- ./certificate.yaml
- ./zitadel-acces-key.yaml
- ./deployment.yaml
- ./service.yaml
- ./horizontalPodAutoScaler.yaml
- ./forwardAuth.yaml

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/instance: gh-authz
app.kubernetes.io/name: gh-authz
name: gh-authz
spec:
ports:
- name: gin
port: 443
protocol: TCP
targetPort: 443
selector:
app.kubernetes.io/instance: gh-authz
app.kubernetes.io/name: gh-authz
type: ClusterIP

View File

@@ -1,12 +1,12 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: zitadel
name: gh-authz
spec:
project: generations-heritage-vv
source:
repoURL: 'https://github.com/vcscsvcscs/GenerationsHeritage'
path: deployment/zitadel
path: deployment/authZ
targetRevision: main
kustomize:
namespace: generations-heritage

View File

@@ -39,7 +39,13 @@ spec:
volumeMounts:
- name: gh-backend-certs
mountPath: /etc/gh-backend/ssl
- name: zitadel-service-account
mountPath: /etc/gh-backend/zitadel
volumes:
- name: gh-backend-certs
secret:
secretName: gh-backend-tls
- name: zitadel-service-account
secret:
secretName: zitadel-service-account

View File

@@ -1,4 +1,3 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
@@ -14,6 +13,5 @@ spec:
services:
- name: gh-backend
port: 443
passHostHeader: true
scheme: https
tls: {}
serversTransport: gh-backend

View File

@@ -1,7 +1,7 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: memraph-certificate
name: memgraph-certificate
annotations:
argocd.argoproj.io/hook: PreSync
spec:

View File

@@ -4,6 +4,7 @@ namespace: generations-heritage
resources:
- ./certificates.yaml
- ./secrets.yaml
helmCharts:
- name: memgraph

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: memgraph-secrets
annotations:
argocd.argoproj.io/hook: PreSync
labels:
secret-generator.cs.sap.com/enabled: "true"
stringData:
USER: memgraph
PASSWORD: "%generate"

View File

@@ -1,52 +1,23 @@
image:
repository: memgraph/memgraph
# Overrides the image tag whose default is v{{ .Chart.AppVersion }}
tag: ""
pullPolicy: IfNotPresent
replicaCount: 1
service:
type: ClusterIP
port: 7687
targetPort: 7687
protocol: TCP
annotations: {}
tag: "2.20.0"
persistentVolumeClaim:
storagePVC: true
storagePVCSize: 2Gi
logPVC: true
logPVCSize: 256Mi
storageSize: 2Gi
memgraphConfig:
- "--also-log-to-stderr=true"
- "--bolt-cert-file=/etc/memgraph/ssl/tls.crt"
- "--bolt-key-file=/etc/memgraph/ssl/tls.key"
# Annotations to add to the statefulSet
statefulSetAnnotations: {}
# Annotations to add to the Pod
podAnnotations: {}
resources:
{}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
env:
- name: MEMGRAPH_USER
valueFrom:
secretKeyRef:
name: memgraph-secrets
key: USER
- name: MEMGRAPH_PASSWORD
valueFrom:
secretKeyRef:
name: memgraph-secrets
key: PASSWORD

View File

@@ -0,0 +1,6 @@
apiVersion: traefik.containo.us/v1alpha1
kind: ServersTransport
metadata:
name: server-transport
spec:
insecureSkipVerify: true

View File

@@ -1,113 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: zitadel-cert-creator
annotations:
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/sync-wave: "2"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-creator
rules:
- apiGroups: [ "" ]
resources: [ "secrets" ]
verbs: [ "create" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: zitadel-cert-creator
annotations:
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/sync-wave: "2"
subjects:
- kind: ServiceAccount
name: zitadel-cert-creator
roleRef:
kind: Role
name: secret-creator
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
name: create-zitadel-cert
annotations:
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/sync-wave: "2"
spec:
template:
spec:
restartPolicy: OnFailure
serviceAccountName: zitadel-cert-creator
containers:
- command:
- /bin/bash
- -ecx
- |
cockroach cert create-client \
--certs-dir /cockroach/cockroach-certs \
--ca-key /cockroach/cockroach-certs/ca.key \
--lifetime 8760h \
zitadel
export SECRET=$(cat <<EOF
{
"apiVersion": "v1",
"kind": "Secret",
"data": {
"ca.crt": "$(base64 /cockroach/cockroach-certs/ca.crt --wrap 0)",
"tls.crt": "$(base64 /cockroach/cockroach-certs/client.zitadel.crt --wrap 0)",
"tls.key": "$(base64 /cockroach/cockroach-certs/client.zitadel.key --wrap 0)"
},
"metadata": {
"name": "db-cockroachdb-zitadel-secret"
},
"type": "kubernetes.io/tls"
}
EOF
)
export APISERVER=https://kubernetes.default.svc SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace) TOKEN=$(cat ${SERVICEACCOUNT}/token) CACERT=${SERVICEACCOUNT}/ca.crt
curl \
--cacert ${CACERT} \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-X POST ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets \
--data "$(echo -n $SECRET | tr -d '\n')"
image: cockroachdb/cockroach:v23.1.8
imagePullPolicy: IfNotPresent
name: create-zitadel-cert
volumeMounts:
- mountPath: /cockroach/cockroach-certs/
name: certs
initContainers:
- command:
- /bin/sh
- -c
- cp -f /certs/* /cockroach-certs/; chmod 0400 /cockroach-certs/*.key
image: busybox
imagePullPolicy: IfNotPresent
name: copy-certs
volumeMounts:
- mountPath: /cockroach-certs/
name: certs
- mountPath: /certs/
name: certs-secret
volumes:
- emptyDir: {}
name: certs
- name: certs-secret
projected:
defaultMode: 420
sources:
- secret:
items:
- key: ca.crt
mode: 256
path: ca.crt
- key: ca.key
mode: 256
path: ca.key
name: cockroachdb-ca-secret

View File

@@ -1,13 +0,0 @@
tls:
enabled: true
annotations:
argocd.argoproj.io/hook: Sync
storage:
persistentVolume:
size: 5Gi
init:
jobAnnotations:
argocd.argoproj.io/hook: Sync

View File

@@ -1,27 +0,0 @@
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: zitadel-server
annotations:
argocd.argoproj.io/hook: PostSync
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`zitadel.varghacsongor.hu`)
priority: 10
services:
- name: zitadel
port: 8080
passHostHeader: true
- kind: Rule
match: Host(`zitadel.varghacsongor.hu`) && Headers(`Content-Type`, `application/grpc`)
priority: 11
services:
- name: zitadel
port: 8080
scheme: h2c
passHostHeader: true
tls: {}

View File

@@ -1,58 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: generations-heritage
resources:
- ./cert-job.yaml
- ./secrets.yaml
- ./ingressRoute.yaml
helmCharts:
- name: cockroachdb
repo: https://charts.cockroachdb.com/
releaseName: cockroachdb
namespace: generations-heritage
version: 12.0.2
valuesFile: cockroach-values.yaml
- name: zitadel
repo: https://charts.zitadel.com
releaseName: zitadel
namespace: generations-heritage
version: 7.10.0
valuesFile: ./values.yaml
patches:
- target:
kind: CronJob
patch: |
- op: replace
path: /apiVersion
value: batch/v1
- target:
name: zitadel-setup
kind: Job
patch: |
- op: add
path: /metadata/annotations/argocd.argoproj.io~1sync-wave
value: 4
- target:
name: zitadel-setup
kind: Job
patch: |
- op: add
path: /metadata/annotations/argocd.argoproj.io~1hook
value: Sync
- target:
name: zitadel-init
kind: Job
patch: |
- op: add
path: /metadata/annotations/argocd.argoproj.io~1sync-wave
value: 3
- target:
name: zitadel-init
kind: Job
patch: |
- op: add
path: /metadata/annotations/argocd.argoproj.io~1hook
value: Sync

View File

@@ -1,23 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: zitadel-masterkey
annotations:
argocd.argoproj.io/hook: PreSync
labels:
secret-generator.cs.sap.com/enabled: "true"
stringData:
masterkey: "%generate"
admin-password: "%generate"
---
apiVersion: v1
kind: Secret
metadata:
name: cockroach-auth
annotations:
argocd.argoproj.io/hook: PreSync
labels:
secret-generator.cs.sap.com/enabled: "true"
stringData:
cockroach-password: "%generate"
user-password: "%generate"

View File

@@ -1,47 +0,0 @@
zitadel:
masterkeySecretName: zitadel-masterkey
configmapConfig:
ExternalSecure: true
ExternalDomain: zitadel.varghacsongor.hu
ExternalPort: 443
TLS:
Enabled: false
Database:
Cockroach:
Host: cockroachdb-public
User:
SSL:
Mode: verify-full
Admin:
SSL:
Mode: verify-full
dbSslCaCrtSecret: cockroachdb-ca-secret
dbSslAdminCrtSecret: cockroachdb-client-secret
dbSslUserCrtSecret: db-cockroachdb-zitadel-secret
annotations:
argocd.argoproj.io/sync-wave: "5"
argocd.argoproj.io/hook: Sync
env:
- name: ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME
value: "admin"
- name: ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD
valueFrom:
secretKeyRef:
name: zitadel-masterkey
key: admin-password
- name: ZITADEL_DATABASE_COCKROACH_USER_PASSWORD
valueFrom:
secretKeyRef:
name: cockroach-auth
key: user-password
- name: ZITADEL_DATABASE_COCKROACH_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: cockroach-auth
key: cockroach-password

View File

@@ -1,12 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -1 +0,0 @@
export const prerender = true;

View File

@@ -1,4 +0,0 @@
<h1>Welcome to SvelteKit</h1>
<p>
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

55
go.mod Normal file
View File

@@ -0,0 +1,55 @@
module github.com/vcscsvcscs/GenerationsHeritage
go 1.23
require (
github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.10.0
github.com/google/uuid v1.6.0
github.com/neo4j/neo4j-go-driver/v5 v5.27.0
github.com/zitadel/zitadel-go/v3 v3.3.2
golang.org/x/net v0.33.0
)
require (
github.com/bytedance/sonic v1.12.6 // indirect
github.com/bytedance/sonic/loader v0.2.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.7 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.23.0 // indirect
github.com/goccy/go-json v0.10.4 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/muhlemmer/gu v0.3.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/zitadel/logging v0.6.1 // indirect
github.com/zitadel/oidc/v3 v3.33.1 // indirect
github.com/zitadel/schema v1.3.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.33.0 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect
golang.org/x/arch v0.12.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.36.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

144
go.sum Normal file
View File

@@ -0,0 +1,144 @@
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bytedance/sonic v1.12.6 h1:/isNmCUF2x3Sh8RAp/4mh4ZGkcFAX/hLrzrK3AvpRzk=
github.com/bytedance/sonic v1.12.6/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.7 h1:SKFKl7kD0RiPdbht0s7hFtjl489WcQ1VyPW8ZzUMYCA=
github.com/gabriel-vasile/mimetype v1.4.7/go.mod h1:GDlAgAyIRT27BhFl53XNAFtfjzOkLaF35JdEG0P7LtU=
github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw=
github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL8sThn8IHr/sO+o=
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc=
github.com/jeremija/gosubmit v0.2.7/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM=
github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM=
github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/vWUetyzY=
github.com/muhlemmer/httpforwarded v0.1.0/go.mod h1:yo9czKedo2pdZhoXe+yDkGVbU0TJ0q9oQ90BVoDEtw0=
github.com/neo4j/neo4j-go-driver/v5 v5.27.0 h1:YdsIxDjAQbjlP/4Ha9B/gF8Y39UdgdTwCyihSxy8qTw=
github.com/neo4j/neo4j-go-driver/v5 v5.27.0/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/zitadel/logging v0.6.1 h1:Vyzk1rl9Kq9RCevcpX6ujUaTYFX43aa4LkvV1TvUk+Y=
github.com/zitadel/logging v0.6.1/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow=
github.com/zitadel/oidc/v3 v3.33.1 h1:e3w9PDV0Mh50/ZiJWtzyT0E4uxJ6RXll+hqVDnqGbTU=
github.com/zitadel/oidc/v3 v3.33.1/go.mod h1:zkoZ1Oq6CweX3BaLrftLEGCs6YK6zDpjjVGZrP10AWU=
github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0=
github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc=
github.com/zitadel/zitadel-go/v3 v3.3.2 h1:sVMd7LKbORONdqcT7D+O6u7AY5v1r/5O1f8Ics9H76s=
github.com/zitadel/zitadel-go/v3 v3.3.2/go.mod h1:1ogo8MBN5iRxHHfDw70Z0k1/PN4O4SDJ0gZ8pVKA6qI=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=

View File

@@ -4,8 +4,8 @@ namespace: argocd
resources:
- ./deployment/cert-issuer.yaml
- ./deployment/server-transport.yaml
- ./deployment/project-argo.yaml
- ./deployment/auth-service-argo.yaml
- ./deployment/memgraph-argo.yaml
- ./deployment/auth-service-argo.yaml
- ./deployment/backend-argo.yaml
- ./deployment/zitadel-argo.yaml

View File

@@ -1,4 +1,4 @@
package utilities
package pkg
import (
"os"

Some files were not shown because too many files have changed in this diff Show More