├── .github
└── workflows
│ └── test.yml
├── .gitignore
├── .idea
├── .gitignore
├── Refractor.iml
├── copyright
│ ├── Notice.xml
│ └── profiles_settings.xml
├── dataSources.xml
├── modules.xml
├── scopes
│ └── Refractor_Copyright.xml
├── sqldialects.xml
└── vcs.xml
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── compose-frontend-svelte.yml
├── default
├── README.md
├── docker
│ └── docker-compose.yml
├── kratos
│ └── kratos.yml
├── nginx
│ └── app.conf
├── postgres
│ └── init.sql
└── svelte
│ ├── .env.production
│ └── README.md
├── deploy
└── kratos
│ └── identity.schema.json
├── dev
├── kratos
│ ├── identity.schema.json
│ └── kratos.dev.yml
└── postgres
│ └── init.sql
├── docker-compose.dev.yml
├── quickstart.sh
├── src
├── auth
│ ├── login.go
│ ├── public.go
│ ├── recovery.go
│ ├── root.go
│ ├── settings.go
│ ├── setupcomplete.go
│ ├── static
│ │ └── style.css
│ ├── templates
│ │ ├── login.html
│ │ ├── partial-foot.html
│ │ ├── partial-head.html
│ │ ├── recovery.html
│ │ ├── settings.html
│ │ ├── setupcomplete.html
│ │ └── verification.html
│ └── verification.go
├── authcheckers
│ └── generic.go
├── domain
│ ├── api.go
│ ├── args.go
│ ├── attachment.go
│ ├── auth.go
│ ├── chat.go
│ ├── command_executor.go
│ ├── error.go
│ ├── game.go
│ ├── group.go
│ ├── http.go
│ ├── infraction.go
│ ├── mail.go
│ ├── mocks
│ │ ├── AttachmentRepo.go
│ │ ├── AttachmentService.go
│ │ ├── AuthRepo.go
│ │ ├── AuthService.go
│ │ ├── Authorizer.go
│ │ ├── ChatRepo.go
│ │ ├── ChatService.go
│ │ ├── ClientCreator.go
│ │ ├── CommandExecutor.go
│ │ ├── FlaggedWordRepo.go
│ │ ├── FlaggedWordService.go
│ │ ├── Game.go
│ │ ├── GameRepo.go
│ │ ├── GameService.go
│ │ ├── GroupRepo.go
│ │ ├── GroupService.go
│ │ ├── InfractionRepo.go
│ │ ├── InfractionService.go
│ │ ├── MailService.go
│ │ ├── PlayerNameRepo.go
│ │ ├── PlayerRepo.go
│ │ ├── PlayerStatsService.go
│ │ ├── RCONClient.go
│ │ ├── RCONService.go
│ │ ├── ServerRepo.go
│ │ ├── ServerService.go
│ │ ├── StatsRepo.go
│ │ ├── UserMetaRepo.go
│ │ ├── UserService.go
│ │ └── WebsocketService.go
│ ├── platform.go
│ ├── player.go
│ ├── player_stats.go
│ ├── querybuilder.go
│ ├── rcon.go
│ ├── search.go
│ ├── server.go
│ ├── stats.go
│ ├── user.go
│ ├── validation.go
│ └── websocket.go
├── games
│ ├── minecraft
│ │ └── minecraft.go
│ └── mordhau
│ │ └── mordhau.go
├── go.mod
├── go.sum
├── internal
│ ├── attachment
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── attachment_repo.go
│ │ │ │ └── attachment_repo_test.go
│ │ └── service
│ │ │ └── attachment_service.go
│ ├── auth
│ │ ├── repos
│ │ │ └── kratos
│ │ │ │ └── authrepo_kratos.go
│ │ └── service
│ │ │ ├── auth_service.go
│ │ │ └── auth_service_test.go
│ ├── authorizer
│ │ ├── authorizer.go
│ │ ├── authorizer_test.go
│ │ ├── refractor_authorizer.go
│ │ └── server_authorizer.go
│ ├── chat
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── chat_handler.go
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── chat_repo.go
│ │ │ │ └── chat_repo_test.go
│ │ └── service
│ │ │ ├── chat_service.go
│ │ │ └── chat_service_test.go
│ ├── command_executor
│ │ ├── command_executor.go
│ │ ├── command_executor_test.go
│ │ └── infraction_command.go
│ ├── flaggedword
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── flagged_word_repo.go
│ │ │ │ └── flagged_word_repo_test.go
│ │ └── service
│ │ │ ├── flagged_word_service.go
│ │ │ └── flagged_word_service_test.go
│ ├── game
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── game_handler.go
│ │ ├── repos
│ │ │ └── file
│ │ │ │ └── game_repo.go
│ │ └── service
│ │ │ ├── game_service.go
│ │ │ └── game_service_test.go
│ ├── group
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ ├── group_handler.go
│ │ │ │ └── group_handler_test.go
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── group_repo.go
│ │ │ │ └── group_repo_test.go
│ │ └── service
│ │ │ ├── group_service.go
│ │ │ └── group_service_test.go
│ ├── infraction
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── infraction_handler.go
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── infraction_repo.go
│ │ │ │ └── infraction_repo_test.go
│ │ ├── service
│ │ │ ├── infraction_service.go
│ │ │ └── infraction_service_test.go
│ │ └── types
│ │ │ ├── ban.go
│ │ │ ├── kick.go
│ │ │ ├── mute.go
│ │ │ └── warning.go
│ ├── mail
│ │ ├── service
│ │ │ └── mail_service.go
│ │ └── templates
│ │ │ └── welcome.html
│ ├── player
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── player_handler.go
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── player
│ │ │ │ ├── player_repo.go
│ │ │ │ └── player_repo_test.go
│ │ │ │ └── playername
│ │ │ │ ├── playername_repo.go
│ │ │ │ └── playername_repo_test.go
│ │ └── service
│ │ │ └── player_service.go
│ ├── player_stats
│ │ └── service
│ │ │ ├── player_stats_service.go
│ │ │ └── player_stats_service_test.go
│ ├── rcon
│ │ ├── clientcreator
│ │ │ └── clientcreator.go
│ │ └── service
│ │ │ ├── rcon_service.go
│ │ │ └── rcon_service_test.go
│ ├── search
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── search_handler.go
│ │ └── service
│ │ │ ├── search_service.go
│ │ │ └── search_service_test.go
│ ├── server
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── server_handler.go
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── server_repo.go
│ │ │ │ └── server_repo_test.go
│ │ └── service
│ │ │ ├── server_service.go
│ │ │ └── server_service_test.go
│ ├── stats
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── stats_handler.go
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── stats_repo.go
│ │ │ │ └── stats_repo_test.go
│ │ └── service
│ │ │ └── stats_service.go
│ ├── user
│ │ ├── delivery
│ │ │ └── http
│ │ │ │ └── user_handler.go
│ │ ├── repos
│ │ │ └── postgres
│ │ │ │ ├── user_repo.go
│ │ │ │ └── user_repo_test.go
│ │ └── service
│ │ │ ├── user_service.go
│ │ │ └── user_service_test.go
│ ├── watchdog
│ │ └── rconserver.go
│ └── websocket
│ │ ├── delivery
│ │ └── http
│ │ │ └── websocket_handler.go
│ │ └── service
│ │ └── websocket_service.go
├── main.go
├── migrations
│ ├── 20210707174342_create_update_modified_at_function.down.sql
│ ├── 20210707174342_create_update_modified_at_function.up.sql
│ ├── 20210710155956_create_groups_table.down.sql
│ ├── 20210710155956_create_groups_table.up.sql
│ ├── 20210710155960_create_usergroups_table.down.sql
│ ├── 20210710155960_create_usergroups_table.up.sql
│ ├── 20210710161007_create_servers_table.down.sql
│ ├── 20210710161007_create_servers_table.up.sql
│ ├── 20210712140232_create_servergroups_table.down.sql
│ ├── 20210712140232_create_servergroups_table.up.sql
│ ├── 20210717152944_create_useroverrides_table.down.sql
│ ├── 20210717152944_create_useroverrides_table.up.sql
│ ├── 20210720160756_create_groups_reorder_func.down.sql
│ ├── 20210720160756_create_groups_reorder_func.up.sql
│ ├── 20210727131757_create_usermeta_table.down.sql
│ ├── 20210727131757_create_usermeta_table.up.sql
│ ├── 20210821133942_create_players_table.down.sql
│ ├── 20210821133942_create_players_table.up.sql
│ ├── 20210821135938_create_playernames_table.down.sql
│ ├── 20210821135938_create_playernames_table.up.sql
│ ├── 20210830202202_create_infractions_table.down.sql
│ ├── 20210830202202_create_infractions_table.up.sql
│ ├── 20210908163101_create_attachments_table.down.sql
│ ├── 20210908163101_create_attachments_table.up.sql
│ ├── 20210915174147_search_player_by_name_func.down.sql
│ ├── 20210915174147_search_player_by_name_func.up.sql
│ ├── 20210926161615_create_chatmessages_table.down.sql
│ ├── 20210926161615_create_chatmessages_table.up.sql
│ ├── 20210929185052_chatmessages_search_setup.down.sql
│ ├── 20210929185052_chatmessages_search_setup.up.sql
│ ├── 20211003133238_create_flaggedwords_table.down.sql
│ ├── 20211003133238_create_flaggedwords_table.up.sql
│ ├── 20211011132959_create_infractionchatmessages_table.down.sql
│ ├── 20211011132959_create_infractionchatmessages_table.up.sql
│ ├── 20211015125247_create_userplayers_table.down.sql
│ ├── 20211015125247_create_userplayers_table.up.sql
│ ├── 20211017134801_infraction_repeal_setup.down.sql
│ ├── 20211017134801_infraction_repeal_setup.up.sql
│ ├── 20211018175905_install_systemtables_extension.down.sql
│ ├── 20211018175905_install_systemtables_extension.up.sql
│ ├── 20211114003439_adjust_permanent_infraction_durations.down.sql
│ └── 20211114003439_adjust_permanent_infraction_durations.up.sql
├── params
│ ├── attachment.go
│ ├── flagged_word.go
│ ├── game.go
│ ├── group.go
│ ├── helpers.go
│ ├── infraction.go
│ ├── rules
│ │ ├── rulegroup.go
│ │ ├── rulegroup_test.go
│ │ └── rules.go
│ ├── search.go
│ ├── server.go
│ ├── user.go
│ ├── validator.go
│ └── validators
│ │ └── inArr.go
├── pkg
│ ├── aeshelper
│ │ └── aes.go
│ ├── api
│ │ ├── errorhandler.go
│ │ ├── middleware
│ │ │ ├── enforcer.go
│ │ │ └── protect.go
│ │ ├── permissions.go
│ │ └── request.go
│ ├── bitperms
│ │ ├── bitperms.go
│ │ └── bitperms_test.go
│ ├── broadcast
│ │ ├── broadcast.go
│ │ └── broadcast_test.go
│ ├── conf
│ │ └── config.go
│ ├── env
│ │ ├── env.go
│ │ └── env_test.go
│ ├── perms
│ │ └── permissions.go
│ ├── pointer
│ │ ├── depointer.go
│ │ └── depointer_test.go
│ ├── querybuilders
│ │ └── psqlqb
│ │ │ ├── postgres_querybuilder.go
│ │ │ └── postgres_querybuilder_test.go
│ ├── regexutils
│ │ ├── named.go
│ │ └── named_test.go
│ ├── structutils
│ │ ├── reflection.go
│ │ └── reflection_test.go
│ ├── tmpl
│ │ └── renderer.go
│ ├── websocket
│ │ ├── client.go
│ │ ├── pool.go
│ │ └── upgrader.go
│ └── whitelist
│ │ ├── whitelist.go
│ │ └── whitelist_test.go
└── platforms
│ ├── mojang
│ └── mojang.go
│ └── playfab
│ └── playfab.go
└── update.sh
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | on: [push, pull_request]
2 | name: Test
3 | jobs:
4 | test:
5 | strategy:
6 | matrix:
7 | go-version: [1.17.x]
8 | os: [ubuntu-latest]
9 | runs-on: ${{ matrix.os }}
10 | steps:
11 | - name: Install Go
12 | uses: actions/setup-go@v2
13 | with:
14 | go-version: ${{ matrix.go-version }}
15 | - name: Checkout code
16 | uses: actions/checkout@v2
17 | - name: Test
18 | working-directory: ./src
19 | run: go test ./...
20 |
21 | test-cache:
22 | runs-on: ubuntu-latest
23 | steps:
24 | - name: Install Go
25 | uses: actions/setup-go@v2
26 | with:
27 | go-version: 1.17.x
28 | - name: Checkout code
29 | uses: actions/checkout@v2
30 | - uses: actions/cache@v2
31 | with:
32 | path: |
33 | ~/go/pkg/mod
34 | ~/.cache/go-build
35 | key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
36 | restore-keys: |
37 | ${{ runner.os }}-go-
38 | - name: Test
39 | working-directory: ./src
40 | run: go test ./...
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | app.env
2 |
3 | data/
4 |
5 | *.bak
6 |
7 | # the quickstart script will automatically create these files from their starting values
8 | # in the defaults folder so we don't need to track changes to them, only their defaults.
9 | /deploy/kratos/kratos.yml
10 | /deploy/postgres/init.sql
11 | /deploy/nginx/app.conf
12 | /deploy/backup/
13 | /docker-compose.yml
14 |
15 | # Ignore frontend
16 | /Refractor-Svelte
17 |
18 | .neversetup
19 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 | /webResources.xml
10 |
--------------------------------------------------------------------------------
/.idea/Refractor.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/copyright/Notice.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/dataSources.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | postgresql
6 | true
7 | org.postgresql.Driver
8 | jdbc:postgresql://localhost:5432/refractor
9 | $ProjectFileDir$
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/scopes/Refractor_Copyright.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/sqldialects.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:alpine AS build
2 |
3 | # Install build tools
4 | RUN apk --no-cache add gcc g++ make git
5 |
6 | # Set build env variables
7 | ENV GO111MODULE=on \
8 | CGO_ENABLED=1 \
9 | GOOS=linux \
10 | GOARCH=amd64
11 |
12 | WORKDIR /build
13 |
14 | COPY src/go.mod .
15 | COPY src/go.sum .
16 | RUN go mod download
17 |
18 | COPY /.git .
19 | COPY /src .
20 |
21 | RUN go build -ldflags "-s -w -X main.VERSION=`echo $(git rev-parse --abbrev-ref HEAD):$(git describe --exact-match --tags 2> /dev/null || git rev-parse --short HEAD)`" -o refractor-bin main.go
22 |
23 | # Create actual container
24 | FROM alpine
25 |
26 | RUN apk --no-cache add ca-certificates
27 |
28 | WORKDIR /var/refractor
29 |
30 | # Create directories where folders containing static assets are located. This is likely not the ideal way to do this.
31 | # However, it works fine! If many more static assets are added, a more scalable solution would be warranted.
32 | RUN mkdir ./auth
33 | RUN mkdir ./auth/templates
34 | RUN mkdir ./auth/static
35 | RUN mkdir ./internal
36 | RUN mkdir ./internal/mail
37 | RUN mkdir ./internal/mail/templates
38 |
39 | # Copy the binary from the build stage into /var/refractor
40 | COPY --from=build /build/refractor-bin ./refractor
41 | COPY --from=build /build/auth/templates ./auth/templates
42 | COPY --from=build /build/auth/static ./auth/static
43 | COPY --from=build /build/internal/mail/templates ./internal/mail/templates
44 |
45 | ENTRYPOINT PORT=80 /var/refractor/refractor
46 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Dev commands
2 | up:
3 | docker-compose -f docker-compose.dev.yml up --build --force-recreate
4 | down:
5 | docker-compose -f docker-compose.dev.yml down
6 |
7 | # Prod commands
8 | prod-remake-nginx:
9 | docker-compose -f docker-compose.yml -f compose-frontend-svelte.yml up -d --force-recreate --build nginx
10 | prod-remake-refractor:
11 | docker-compose -f docker-compose.yml -f compose-frontend-svelte.yml up -d --force-recreate --build refractor
12 | prod-remake-svelte:
13 | docker-compose -f docker-compose.yml -f compose-frontend-svelte.yml up -d --force-recreate --build refractor-frontend
14 | deploy-cleanup:
15 | rm -f ./docker-compose.yml ./deploy/kratos/kratos.yml ./deploy/postgres/init.sql ./deploy/nginx/app.conf \
16 | ./Refractor-Svelte/rollup.config.js ./.neversetup 2> /dev/null
--------------------------------------------------------------------------------
/compose-frontend-svelte.yml:
--------------------------------------------------------------------------------
1 | version: "3.7"
2 |
3 | services:
4 | refractor-frontend:
5 | container_name: "refractor-frontend"
6 | build:
7 | dockerfile: Dockerfile
8 | context: ./Refractor-Svelte
9 | ports:
10 | - "3000:3000"
11 | networks:
12 | - intranet
13 |
--------------------------------------------------------------------------------
/default/README.md:
--------------------------------------------------------------------------------
1 | # /default
2 |
3 | The `default` folder contains the default configuration to be used in deployment.
4 |
5 | The `quickstart.sh` script works by making copies of the config files with `default`
6 | to their correct locations, collecting info from the user (e.g domain, email, etc)
7 | and then replacing the variables found in the copied default files with the values which
8 | were provided by the user.
9 |
10 | ## Example Flow
11 | This example flow will use the default file `/default/kratos/kratos.yml` as an example.
12 |
13 | 1. The user runs `/quickstart.sh`. It detects that `/deploy/kratos/kratos.yml`
14 | does not exist, so it makes a copy of `/default/kratos/kratos.yml` to the location
15 | `/deploy/kratos/kratos.yml`.
16 | 2. In the quickstart script, the user will information about their deployment
17 | environment.
18 | 3. The information provided by the user which is relevant to `kratos.yml` will
19 | be populated in the `/deploy/kratos/kratos.yml` (copied from default) by replacing
20 | the placeholders (e.g `{{DOMAIN}}`) with the correct values.
21 | 4. If the user ever chooses to re-run the quickstart script, they will be given
22 | the option to overwrite their config files. If they choose to do so, the file at
23 | `/deploy/kratos/kratos.yml` will be moved to `/deploy/backup/kratos/kratos.yml`
24 | and a fresh copy of `kratos.yml` will be copied from the default to the deploy location.
--------------------------------------------------------------------------------
/default/kratos/kratos.yml:
--------------------------------------------------------------------------------
1 | version: v0.6.3-alpha.1
2 |
3 | dsn: "{{KRATOS_DSN}}"
4 |
5 | serve:
6 | public:
7 | base_url: https://{{DOMAIN}}/kp/
8 | cors:
9 | enabled: true
10 | allowed_origins:
11 | - https://{{DOMAIN}}
12 | allowed_methods:
13 | - POST
14 | - GET
15 | - PUT
16 | - PATCH
17 | - DELETE
18 | allowed_headers:
19 | - Authorization
20 | - Cookie
21 | exposed_headers:
22 | - Content-Type
23 | - Set-Cookie
24 | admin:
25 | base_url: http://127.0.0.1:4434/
26 |
27 | selfservice:
28 | default_browser_return_url: https://{{DOMAIN}}/
29 | whitelisted_return_urls:
30 | - https://{{DOMAIN}}/
31 |
32 | methods:
33 | password:
34 | enabled: true
35 | link:
36 | enabled: true
37 |
38 | flows:
39 | error:
40 | ui_url: https://{{DOMAIN}}/k/error
41 |
42 | settings:
43 | ui_url: https://{{DOMAIN}}/k/settings
44 | privileged_session_max_age: 15m
45 |
46 | recovery:
47 | enabled: true
48 | ui_url: https://{{DOMAIN}}/k/recovery
49 |
50 | verification:
51 | enabled: true
52 | ui_url: https://{{DOMAIN}}/k/verify
53 | after:
54 | default_browser_return_url: https://{{DOMAIN}}/k/activated
55 |
56 | logout:
57 | after:
58 | default_browser_return_url: https://{{DOMAIN}}/k/login
59 |
60 | login:
61 | ui_url: https://{{DOMAIN}}/k/login
62 | lifespan: 10m
63 |
64 | log:
65 | level: debug
66 | format: text
67 | leak_sensitive_values: true
68 |
69 | secrets:
70 | cookie:
71 | - {{COOKIE_SECRET}}
72 |
73 | hashers:
74 | argon2:
75 | parallelism: 1
76 | memory: 128MB
77 | iterations: 2
78 | salt_length: 16
79 | key_length: 16
80 |
81 | session:
82 | lifespan: 72h
83 |
84 | identity:
85 | default_schema_url: file:///etc/config/kratos/identity.schema.json
86 |
--------------------------------------------------------------------------------
/default/nginx/app.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name {{DOMAIN}};
4 |
5 | location / {
6 | return 301 https://$host$request_uri;
7 | }
8 |
9 | location /.well-known/acme-challenge/ {
10 | root /var/www/certbot;
11 | }
12 | }
13 |
14 | server {
15 | listen 443 ssl;
16 | server_name {{DOMAIN}};
17 |
18 | ssl_certificate /etc/letsencrypt/live/{{DOMAIN}}/fullchain.pem;
19 | ssl_certificate_key /etc/letsencrypt/live/{{DOMAIN}}/privkey.pem;
20 |
21 | # Route API calls to the backend API.
22 | location /api/ {
23 | proxy_pass http://refractor:4000;
24 | proxy_redirect off;
25 | proxy_set_header Host $host;
26 | proxy_set_header X-Real-IP $remote_addr;
27 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
28 | proxy_set_header X-Forwarded-Host $server_name;
29 | }
30 |
31 | location /ws {
32 | proxy_pass http://refractor:4000;
33 | proxy_http_version 1.1;
34 | proxy_set_header Upgrade $http_upgrade;
35 | proxy_set_header Connection "Upgrade";
36 | proxy_set_header Host $host;
37 | }
38 |
39 | # Routes to the public Ory Kratos API. The ^~ is a special nginx matcher which is used to perform the longest
40 | # non regex match against the /kp/ URI. If a request reaches this block, no further matching takes place.
41 | # Additionally, due to the ending / after /kp/ and :4433/ in the proxy pass directive, the /kp/ portion of the
42 | # request URI will be stripped away once routed to the public kratos API.
43 | #
44 | # For example, a request to /kp/self-service/login/browser will be routed to Ory Kratos' Public API
45 | # as the following: /self-service/login/browser
46 | location ^~ /kp/ {
47 | proxy_pass http://refractor-kratos:4433/;
48 | proxy_set_header Host $host;
49 | proxy_pass_request_headers on;
50 | }
51 |
52 | # Routes to the backend server-side auth pages. Anything which starts with /k and does not match /kp/ (seen above)
53 | # will be handled in this block.
54 | location /k {
55 | proxy_pass http://refractor:4455;
56 | proxy_set_header Host $host;
57 | proxy_pass_request_headers on;
58 | }
59 |
60 | # Routes to the frontend. Anything which doesn't match any of the above matchers will be handled in this block.
61 | location / {
62 | proxy_pass http://refractor-frontend:3000;
63 | proxy_redirect off;
64 | proxy_set_header Host $host;
65 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/default/postgres/init.sql:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of Refractor.
3 | *
4 | * Refractor is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | CREATE DATABASE refractor;
--------------------------------------------------------------------------------
/default/svelte/.env.production:
--------------------------------------------------------------------------------
1 | VITE_COMMUNITY_NAME={{COMMUNITY_NAME}}
2 | VITE_KRATOS_ROOT={{KRATOS_ROOT}}
3 | VITE_AUTH_ROOT={{AUTH_ROOT}}
4 | VITE_API_ROOT={{API_ROOT}}
5 | VITE_WS_ROOT={{WEBSOCKET_ROOT}}
--------------------------------------------------------------------------------
/default/svelte/README.md:
--------------------------------------------------------------------------------
1 | # Svelte Defaults
2 |
3 | The files alongside this readme are the default config files for the Refractor-Svelte
4 | frontend application.
--------------------------------------------------------------------------------
/deploy/kratos/identity.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "title": "Person",
5 | "type": "object",
6 | "properties": {
7 | "traits": {
8 | "type": "object",
9 | "properties": {
10 | "email": {
11 | "type": "string",
12 | "format": "email",
13 | "title": "Email",
14 | "minLength": 3,
15 | "ory.sh/kratos": {
16 | "credentials": {
17 | "password": {
18 | "identifier": true
19 | }
20 | },
21 | "verification": {
22 | "via": "email"
23 | },
24 | "recovery": {
25 | "via": "email"
26 | }
27 | }
28 | },
29 | "username": {
30 | "type": "string",
31 | "title": "Username",
32 | "minLength": 1,
33 | "ory.sh/kratos": {
34 | "credentials": {
35 | "password": {
36 | "identifier": true
37 | }
38 | }
39 | }
40 | }
41 | },
42 | "required": [
43 | "email",
44 | "username"
45 | ],
46 | "additionalProperties": false
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/dev/kratos/identity.schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$id": "https://schemas.ory.sh/presets/kratos/quickstart/email-password/identity.schema.json",
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "title": "Person",
5 | "type": "object",
6 | "properties": {
7 | "traits": {
8 | "type": "object",
9 | "properties": {
10 | "email": {
11 | "type": "string",
12 | "format": "email",
13 | "title": "Email",
14 | "minLength": 3,
15 | "ory.sh/kratos": {
16 | "credentials": {
17 | "password": {
18 | "identifier": true
19 | }
20 | },
21 | "verification": {
22 | "via": "email"
23 | },
24 | "recovery": {
25 | "via": "email"
26 | }
27 | }
28 | },
29 | "username": {
30 | "type": "string",
31 | "title": "Username",
32 | "minLength": 1,
33 | "ory.sh/kratos": {
34 | "credentials": {
35 | "password": {
36 | "identifier": true
37 | }
38 | }
39 | }
40 | }
41 | },
42 | "required": [
43 | "email",
44 | "username"
45 | ],
46 | "additionalProperties": false
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/dev/kratos/kratos.dev.yml:
--------------------------------------------------------------------------------
1 | version: v0.6.3-alpha.1
2 |
3 | dsn: postgres://postgres:password@postgresd:5432:4455ratos?sslmode=disable&max_conns=20&max_idle_conns=4
4 |
5 | serve:
6 | public:
7 | base_url: http://127.0.0.1:4433/
8 | cors:
9 | enabled: true
10 | allowed_origins:
11 | - http://127.0.0.1:3000
12 | allowed_methods:
13 | - POST
14 | - GET
15 | - PUT
16 | - PATCH
17 | - DELETE
18 | allowed_headers:
19 | - Authorization
20 | - Cookie
21 | exposed_headers:
22 | - Content-Type
23 | - Set-Cookie
24 | admin:
25 | base_url: http://127.0.0.1:4434/
26 |
27 | selfservice:
28 | default_browser_return_url: http://127.0.0.1:3000/
29 | whitelisted_return_urls:
30 | - http://127.0.0.1:3000
31 |
32 | methods:
33 | password:
34 | enabled: true
35 | link:
36 | enabled: true
37 |
38 | flows:
39 | error:
40 | ui_url: http://127.0.0.1:4455/k/error
41 |
42 | settings:
43 | ui_url: http://127.0.0.1:4455/k/settings
44 | privileged_session_max_age: 15m
45 |
46 | recovery:
47 | enabled: true
48 | ui_url: http://127.0.0.1:4455/k/recovery
49 |
50 | verification:
51 | enabled: true
52 | ui_url: http://127.0.0.1:4455/k/verify
53 | after:
54 | default_browser_return_url: http://127.0.0.1:4455/k/activated
55 |
56 | logout:
57 | after:
58 | default_browser_return_url: http://127.0.0.1:4455/k/login
59 |
60 | login:
61 | ui_url: http://127.0.0.1:4455/k/login
62 | lifespan: 10m
63 |
64 | log:
65 | level: debug
66 | format: text
67 | leak_sensitive_values: true
68 |
69 | secrets:
70 | cookie:
71 | - PLEASE-CHANGE-ME-I-AM-VERY-INSECURE
72 |
73 | hashers:
74 | argon2:
75 | parallelism: 1
76 | memory: 128MB
77 | iterations: 2
78 | salt_length: 16
79 | key_length: 16
80 |
81 | session:
82 | lifespan: 72h
83 |
84 | identity:
85 | default_schema_url: file:///etc/config/kratos/identity.schema.json
86 |
87 | #courier:
88 | # smtp:
89 | # connection_uri: smtp://@mailhog:1025/
90 |
--------------------------------------------------------------------------------
/dev/postgres/init.sql:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of Refractor.
3 | *
4 | * Refractor is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | CREATE DATABASE refractor;
--------------------------------------------------------------------------------
/docker-compose.dev.yml:
--------------------------------------------------------------------------------
1 | version: "3.7"
2 |
3 | services:
4 | postgresd:
5 | container_name: "refractor_postgres"
6 | image: postgres:9.6
7 | ports:
8 | - "5432:5432"
9 | environment:
10 | - POSTGRES_USER=postgres
11 | - POSTGRES_PASSWORD=password
12 | - POSTGRES_DB=kratos
13 | volumes:
14 | - ./dev/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
15 | networks:
16 | - intranet
17 |
18 | kratos-migrate:
19 | container_name: "refractor_kratos_migrate"
20 | depends_on:
21 | - postgresd
22 | image: oryd/kratos:v0.6.3-alpha.1
23 | environment:
24 | - DSN=postgres://postgres:password@postgresd:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
25 | volumes:
26 | - type: bind
27 | source: ./dev/kratos
28 | target: /etc/config/kratos
29 | command: -c /etc/config/kratos/kratos.dev.yml migrate sql -e --yes
30 | restart: on-failure
31 | networks:
32 | - intranet
33 |
34 | kratos:
35 | container_name: "refractor_kratos"
36 | depends_on:
37 | - postgresd
38 | - kratos-migrate
39 | image: oryd/kratos:v0.6.3-alpha.1
40 | ports:
41 | - "4433:4433" # auth
42 | - "4434:4434" # admin
43 | restart: unless-stopped
44 | environment:
45 | - DSN=postgres://postgres:password@postgresd:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
46 | - LOG_LEVEL=trace
47 | - COURIER_SMTP_CONNECTION_URI=smtp://@mailhog:1025/
48 | - COURIER_SMTP_FROM_ADDRESS=noreply@refractor
49 | command: serve -c /etc/config/kratos/kratos.dev.yml --dev --watch-courier
50 | volumes:
51 | - type: bind
52 | source: ./dev/kratos
53 | target: /etc/config/kratos
54 | networks:
55 | - intranet
56 |
57 | mailhog:
58 | hostname: "mailhog"
59 | container_name: "refractor_mailhog"
60 | image: mailhog/mailhog
61 | ports:
62 | - "1025:1025"
63 | - "8025:8025"
64 | networks:
65 | - intranet
66 |
67 | networks:
68 | intranet:
69 |
--------------------------------------------------------------------------------
/src/auth/public.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of Refractor.
3 | *
4 | * Refractor is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | package auth
19 |
20 | import (
21 | "Refractor/pkg/conf"
22 | kratos "github.com/ory/kratos-client-go"
23 | )
24 |
25 | type publicHandlers struct {
26 | client *kratos.APIClient
27 | config *conf.Config
28 | }
29 |
30 | func NewPublicHandlers(client *kratos.APIClient, config *conf.Config) *publicHandlers {
31 | return &publicHandlers{
32 | client: client,
33 | config: config,
34 | }
35 | }
36 |
37 | type Node struct {
38 | Label string
39 | Disabled bool
40 | Name string
41 | Required bool
42 | Type string
43 | Value string
44 | }
45 |
46 | type Message struct {
47 | ID int64
48 | Text string
49 | Type string
50 | }
51 |
52 | type RenderData struct {
53 | Action string
54 | Method string
55 | FlowID string
56 | UiNodes []Node
57 | Messages []Message
58 | }
59 |
--------------------------------------------------------------------------------
/src/auth/root.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of Refractor.
3 | *
4 | * Refractor is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | package auth
19 |
20 | import (
21 | "fmt"
22 | "github.com/labstack/echo/v4"
23 | "net/http"
24 | )
25 |
26 | func (h *publicHandlers) RootHandler(c echo.Context) error {
27 | return c.Redirect(http.StatusTemporaryRedirect,
28 | fmt.Sprintf("%s/self-service/login/browser", h.config.KratosPublic))
29 | }
30 |
--------------------------------------------------------------------------------
/src/auth/setupcomplete.go:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of Refractor.
3 | *
4 | * Refractor is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 |
18 | package auth
19 |
20 | import (
21 | "Refractor/domain"
22 | "fmt"
23 | "github.com/labstack/echo/v4"
24 | "net/http"
25 | )
26 |
27 | func (h *publicHandlers) SetupCompleteHandler(c echo.Context) error {
28 | user, ok := c.Get("user").(*domain.AuthUser)
29 | if !ok {
30 | return fmt.Errorf("could not get AuthUser from context")
31 | }
32 |
33 | // Check if this user has a verified address
34 | verified := false
35 | for _, address := range user.Identity.VerifiableAddresses {
36 | if address.Verified {
37 | verified = true
38 | break
39 | }
40 | }
41 |
42 | if !verified {
43 | // If this user is not yet verified, redirect them to the frontend application where they will be notified that
44 | // they have to verify their email.
45 | return c.JSON(http.StatusTemporaryRedirect, h.config.FrontendRoot)
46 | }
47 |
48 | return c.Render(http.StatusOK, "setupcomplete", h.config.FrontendRoot)
49 | }
50 |
--------------------------------------------------------------------------------
/src/auth/templates/login.html:
--------------------------------------------------------------------------------
1 |
17 |
18 | {{ define "login" }}
19 | {{ template "head" . }}
20 |
21 |
Sign in
22 |
23 |
48 |
49 |
50 |
51 | {{ template "foot" . }}
52 | {{ end }}
--------------------------------------------------------------------------------
/src/auth/templates/partial-foot.html:
--------------------------------------------------------------------------------
1 |
17 |
18 | {{ define "foot" }}
19 |