Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d05f11b
add: Dockerfile
szymekc Nov 24, 2023
af95657
Merge pull request #1 from SigmaProductions/feature/add-Dockerfile
szymekc Nov 24, 2023
e51622a
Changed provider to postgres; fixed connection string
senbar Nov 24, 2023
4d1831d
fix: publish appsettings.json
szymekc Nov 24, 2023
70ed7f2
Fixed migrations, added post chat and fixed get chat
senbar Dec 6, 2023
8e7aab6
Merge branch 'development' of https://github.com/SigmaProductions/Sig…
senbar Dec 6, 2023
e50857e
Added Signalr; Added post for messages
senbar Dec 10, 2023
42a10ec
Fixed migrations missing semicolon; Fixed tuple returned on generatin…
senbar Dec 10, 2023
384f7f7
Added seeding first chat to migrations
senbar Dec 10, 2023
ea581af
add: sigmaChat docker network
szymekc Dec 10, 2023
12d9df4
Added authentication
senbar Dec 13, 2023
f4ab706
Merge branch 'development' of https://github.com/SigmaProductions/Sig…
senbar Dec 13, 2023
1907e57
Remove authentication on db update call
senbar Dec 14, 2023
d6c6077
CORS for docker
senbar Dec 14, 2023
387e20a
User entites added; Reference from messages to users added, now mappi…
senbar Dec 22, 2023
ed3564d
Message order fix; Fixed timestamp being only date
senbar Dec 30, 2023
93c213f
Three things:
senbar Feb 1, 2024
f6d8dcf
Merge pull request #2 from senbar/development
senbar Feb 1, 2024
bca7f38
Fix for notifying all subscribers.
senbar Feb 2, 2024
79b171f
Merge branch 'development' of https://github.com/SigmaProductions/Sig…
senbar Feb 2, 2024
40ec7b1
Error was thrown when subscription was expired, made it just skip thi…
senbar Feb 2, 2024
c27e669
Fix for sql timeout and option type json utils
senbar Feb 15, 2024
6962aa3
feature: added logic for blob storage; renamed db modules to query
senbar Feb 15, 2024
1e9d168
Merge pull request #3 from senbar/development
senbar Feb 15, 2024
ad3992c
Feature: pagination
senbar Feb 19, 2024
6470273
Merge branch 'development' of https://github.com/SigmaProductions/Sig…
senbar Feb 19, 2024
6344dab
Add: build + deployment pipeline
izabelasowi Mar 28, 2024
55eba4d
Merge pull request #4 from SigmaProductions/feature/cicd
senbar Apr 22, 2024
d4af797
feat: Migrate to minIO and finish up users profile pics
senbar Apr 23, 2024
e281867
fix: Update PostgreSQL data volume path
danielkluska Apr 24, 2024
80cbd2c
Merge pull request #5 from SigmaProductions/fix_db_volume
szymekc May 17, 2024
3206e13
fix: Remove clutter from dev setup
senbar Jan 4, 2026
4433472
Merge branch 'development' of https://github.com/senbar/SigmaChatServ…
senbar Jan 4, 2026
1005a52
Merge pull request #6 from senbar/development
senbar Jan 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/checkout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
on:
push:
branches:
- development

env:
IMAGE_NAME: sigmaproductions/sigmachatserver

jobs:
build:
runs-on: [self-hosted, build]
steps:
- name: Set build tag
run: |
echo "IMAGE_TAG=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
- name: Checkout repository
uses: actions/checkout@v2
- name: Configure appsettings.json
env:
appsettings: ${{ secrets.appsettings }}
run: |
echo "$appsettings" > appsettings.json
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build the Docker image
run: docker build . --file Dockerfile --tag ${IMAGE_NAME}:${IMAGE_TAG}
- name: Publish the Docker image
run: docker push ${IMAGE_NAME}:${IMAGE_TAG}
deploy:
needs: build
runs-on: [self-hosted, deploy]
steps:
- name: Set build tag
run: |
echo "IMAGE_TAG=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
- name: Checkout repository
uses: actions/checkout@v2
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Pull and deploy
env:
AZURITE_ACCOUNTS: ${{ secrets.azurite_accounts }}
run: docker-compose -f compose.prod.yaml pull &&
docker-compose -f compose.prod.yaml up -d
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,5 @@ paket-files/
# JetBrains Rider
.idea/
*.sln.iml

appsettings.json
30 changes: 30 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "Build: SigmaChatServer.fsproj",
"program": "${workspaceFolder}/bin/Debug/net7.0/SigmaChatServer.App.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "F#: <project-name> Debug",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/SigmaChatServer.fsproj"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
12 changes: 12 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "msbuild",
"problemMatcher": ["$msCompile"],
"group": "build",
"label": "Build: SigmaChatServer.fsproj",
"detail": "Build the SigmaChatServer.fsproj project using dotnet build"
}
]
}
90 changes: 90 additions & 0 deletions BlobHandlers.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
namespace SigmaChatServer

module BlobHandlers =

open Microsoft.AspNetCore.Http
open Giraffe
open System.Data
open SigmaChatServer.Models
open Npgsql
open Azure.Storage.Blobs
open System
open Giraffe.HttpStatusCodeHandlers.RequestErrors
open UserQueries
open System.IO
open UserQueries
open Minio
open Minio.DataModel.Args
open Microsoft.Extensions.Configuration

[<CLIMutable>]
type FormModel = { Image: IFormFile; Test: string }
// Check if file is an image based on MIME type
let isImage (contentType: string) =
match contentType with
| "image/jpeg"
| "image/png"
| "image/gif" -> true
| _ -> false

let getPublicBlobUrl (config: IConfiguration) blobName =
let minioSettings = config.GetSection("Minio")
minioSettings.GetValue<string>("PublicBucketUrl") + blobName

let private processHttpFileRequest (next: HttpFunc) (ctx: HttpContext) handler =
task {
match ctx.Request.HasFormContentType with
| true ->
let! form = ctx.Request.ReadFormAsync() |> Async.AwaitTask
let files = form.Files

if files.Count > 0 then
let file = files.[0]
return! handler file
else
return! badRequest (text "No files uploaded") next ctx
| false -> return! badRequest (text "Unsupported media type") next ctx
}

let private uploadProfilePicture (userId: string) (next: HttpFunc) (ctx: HttpContext) (file: IFormFile) =
task {
let containerClient = ctx.GetService<IMinioClient>()
let minioSettings = ctx.GetService<IConfiguration>().GetSection("Minio")

let guid = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName)

let fileModel =
{ UserId = userId
BlobName = guid
OriginalFilename = file.FileName }

use stream = file.OpenReadStream()

let putArgs =
(new PutObjectArgs())
.WithBucket(minioSettings.GetValue<string>("PublicBucketName"))
.WithObject(fileModel.BlobName)
.WithObjectSize(stream.Length)
.WithContentType(file.ContentType)
.WithStreamData(stream)

let! _ = containerClient.PutObjectAsync(putArgs)
let! _ = upsertProfilePicture ctx fileModel

let blobUrl = getPublicBlobUrl minioSettings fileModel.BlobName
return! text blobUrl next ctx
}

let profilePictureUploadHandler (next: HttpFunc) (ctx: HttpContext) =
let userId = ctx.User.Identity.Name
uploadProfilePicture userId next ctx |> processHttpFileRequest next ctx


//Note:
// let presignesArgs =
// (new PresignedGetObjectArgs())
// .WithBucket("public-jehovahs-pictures")
// .WithObject(guidName)
// .WithExpiry(60)

// let! z = containerClient.PresignedGetObjectAsync(presignesArgs)
18 changes: 0 additions & 18 deletions ChatDb.fs

This file was deleted.

39 changes: 39 additions & 0 deletions DapperHelper.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Dapper.Extensions

open System
open Dapper

let extractValue (x: obj) =
match x with
| null -> null
| _ ->
match x.GetType().GetProperty("Value") with
| null -> x
| prop -> prop.GetValue(x)

let (+>) (map: Map<string, obj>) (key, value) = map.Add(key, extractValue value)
let singleParam (key, value) = (Map.empty) +> (key, value)

type OptionHandler<'T>() =
inherit SqlMapper.TypeHandler<option<'T>>()

override __.SetValue(param, value) =
let valueOrNull =
match value with
| Some x -> box x
| None -> null

param.Value <- valueOrNull

override __.Parse value =
if isNull value || value = box DBNull.Value then
None
else
Some(value :?> 'T)

let registerTypeHandlers () =
SqlMapper.AddTypeHandler(OptionHandler<Guid>())
SqlMapper.AddTypeHandler(OptionHandler<int64>())
SqlMapper.AddTypeHandler(OptionHandler<int>())
SqlMapper.AddTypeHandler(OptionHandler<string>())
SqlMapper.AddTypeHandler(OptionHandler<DateTime>())
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine AS build

WORKDIR /app

# Copy source code and compile
COPY ./ ./
RUN dotnet restore

RUN dotnet publish -o bin

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine AS runtime

WORKDIR /app
COPY --from=build /app/bin .

ENTRYPOINT ["dotnet", "SigmaChatServer.App.dll"]
Loading
Loading