Compare commits

...

2 Commits

112 changed files with 17313 additions and 17242 deletions
+24
View File
@@ -0,0 +1,24 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C#: FamilyTreeAPI",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/FamilyTreeAPI/bin/Debug/net10.0/FamilyTreeAPI",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole",
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"serverReadyAction": {
"action": "openUrl",
"pattern": "Now listening on:\\s+(https?://\\S+)",
"uriFormat": "%s/swagger/index.html"
}
}
]
}
+2 -2
View File
@@ -3,7 +3,7 @@
# This stage is used when running from VS in fast mode (Default for Debug configuration) # This stage is used when running from VS in fast mode (Default for Debug configuration)
#FROM mcr.microsoft.com/dotnet/aspnet:9::.0 AS base #FROM mcr.microsoft.com/dotnet/aspnet:9::.0 AS base
ARG BUILD_CONFIGURATION=Release ARG BUILD_CONFIGURATION=Release
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src WORKDIR /src
COPY ["FamilyTreeAPI/FamilyTreeAPI.csproj", "FamilyTreeAPI/"] COPY ["FamilyTreeAPI/FamilyTreeAPI.csproj", "FamilyTreeAPI/"]
RUN dotnet restore "./FamilyTreeAPI/FamilyTreeAPI.csproj" RUN dotnet restore "./FamilyTreeAPI/FamilyTreeAPI.csproj"
@@ -31,7 +31,7 @@ FROM build AS publish
RUN dotnet publish "./FamilyTreeAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false RUN dotnet publish "./FamilyTreeAPI.csproj" -c Release -o /app/publish /p:UseAppHost=false
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration) # This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
WORKDIR /app WORKDIR /app
ENV ASPNETCORE_HTTP_PORTS=8080 ENV ASPNETCORE_HTTP_PORTS=8080
EXPOSE 8080 EXPOSE 8080
+9 -2
View File
@@ -7,10 +7,9 @@
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath> <DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
<AllowMissingPrunePackageData>true</AllowMissingPrunePackageData>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="HotChocolate.AspNetCore" Version="16.0.0" /> <PackageReference Include="HotChocolate.AspNetCore" Version="16.0.0" />
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="16.0.0" /> <PackageReference Include="HotChocolate.Data.EntityFramework" Version="16.0.0" />
@@ -31,4 +30,12 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.7" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project> </Project>
+24 -3
View File
@@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using System.Text; using System.Text;
using DocumentFormat.OpenXml.Office2010.Drawing.Charts;
using FamilyTreeAPI.Authorization; using FamilyTreeAPI.Authorization;
using FamilyTreeAPI.Entities; using FamilyTreeAPI.Entities;
using FamilyTreeAPI.GraphQL.Query; using FamilyTreeAPI.GraphQL.Query;
@@ -14,6 +13,12 @@ using FamilyTreeAPI.Repository;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Explicitly register the base paths for Linux container execution
builder.Configuration
.SetBasePath(AppContext.BaseDirectory) // <-- Pulls from wherever the binary sits
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
// Add services to the container. // Add services to the container.
#region Services #region Services
var services = builder.Services; var services = builder.Services;
@@ -23,8 +28,10 @@ services.AddControllers();
services.AddEndpointsApiExplorer(); services.AddEndpointsApiExplorer();
services.AddSwaggerGen(); services.AddSwaggerGen();
string skey = "Super Secret SIGN AND VERIFY JWT TOKENS"; string skey = "Super Secret SIGN AND VERIFY JWT TOKENS";
var appSettingsSection = builder.Configuration.GetSection("AppSettings"); var appSettingsSection = builder.Configuration.GetSection("AppSettings");
if (appSettingsSection != null) if (appSettingsSection.Exists())
{ {
services.Configure<AppSettings>(appSettingsSection); services.Configure<AppSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<AppSettings>(); var appSettings = appSettingsSection.Get<AppSettings>();
@@ -32,10 +39,13 @@ if (appSettingsSection != null)
skey = appSettings.Secret; skey = appSettings.Secret;
else else
{ {
skey = builder.Configuration.GetValue<string>("AppSettings:Secret"); string tkey = builder.Configuration.GetValue<string>("AppSettings:Secret") ?? string.Empty;
if (!string.IsNullOrEmpty(tkey))
skey = tkey;
} }
} }
var key = Encoding.ASCII.GetBytes(skey); var key = Encoding.ASCII.GetBytes(skey);
services.AddAuthentication(x => services.AddAuthentication(x =>
@@ -174,6 +184,17 @@ app.Run();
#endregion #endregion
/* /*
<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="appsettings.Development.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
https://www.youtube.com/watch?v=WQFx2m5Ub9M https://www.youtube.com/watch?v=WQFx2m5Ub9M
@@ -8,35 +8,11 @@
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
}, },
"dotnetRunMessages": true, "dotnetRunMessages": true,
"applicationUrl": "http://localhost:5016", "applicationUrl": "http://localhost:5016"
"applicationUrl1": "http://192.168.8.188:5015"
}, },
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Container (Dockerfile)": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
"environmentVariables": {
"ASPNETCORE_HTTP_PORTS": "8080"
},
"publishAllPorts": true,
"useSSL": false
}
},
"$schema": "https://json.schemastore.org/launchsettings.json", "$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:4559",
"sslPort": 0
}
} }
} }
+6 -4
View File
@@ -2,11 +2,11 @@
"AppSettings": { "AppSettings": {
"Secret": "Super Secret SIGN AND VERIFY JWT TOKENS, BEARER TOKEN USE WHEN CALLING THIS API.", "Secret": "Super Secret SIGN AND VERIFY JWT TOKENS, BEARER TOKEN USE WHEN CALLING THIS API.",
"SQLConnectionString_i": "host=localhost;port=5432;database=FamilyTreeDB_prod;username=postgres;password=Positive~1;", "iSQLConnectionString_i": "host=localhost;port=5432;database=FamilyTreeDB_prod;username=postgres;password=Positive~1;",
"SQLConnectionString": "host=192.168.1.240;port=5432;database=FamilyTreeDB_prod;username=postgres;password=Positive~1;", "SQLConnectionString": "host=192.168.1.240;port=5432;database=FamilyTreeDB_prod;username=postgres;password=Positive~1;",
"ImageFolder": "c:\\temp\\Family", "ImageFolder": "/temp/Family",
"ImportFolder": "c:\\temp" "ImportFolder": "/temp"
}, },
"Logging": { "Logging": {
@@ -17,11 +17,13 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"Kestrel_not_use": { "Kestrel": {
"Endpoints": { "Endpoints": {
"Http": { "Http": {
"Url": "http://*:5015" "Url": "http://*:5015"
} }
} }
} }
} }
+8 -5
View File
@@ -1,17 +1,15 @@
@if (currentUserS() && isAuth) @if (currentUserS() && isAuth == true)
{ {
<div class="flex flex-column justify-between md:flex-row rounded" style="background-color:transparent"> <div class="flex flex-column justify-between md:flex-row rounded" style="background-color:transparent">
<div style="margin-top:5px;padding-right:35px; cursor: pointer;width:400px;"> <div style="margin-top:5px;padding-right:35px; cursor: pointer;width:400px;">
<img (click)="onHome()" src="images/application_image.png" alt="Banner" style="height:80px;width:100%" /> <img (click)="onHome()" src="images/application_image.png" alt="Banner" style="height:80px;width:100%" />
</div> </div>
<div class="flex justify-end items-end flex-row"> <div class="flex justify-end items-end flex-row">
<div class="flex-column"> <div class="flex-column">
<label class=" flex justify-end items-end mr-1 mb-2 myname">{{loginUser}}</label> <label class=" flex justify-end items-end mr-1 mb-2 myname">{{loginUser}}</label>
<div> <div>
<span class="md:hidden flex justify-start"> <!--hidden on md screen show on small-->
<button type="button" pButton icon="pi pi-align-justify" (click)="onemenu.toggle($event);"></button>
<p-menu #onemenu [popup]="true" [model]="oneMenu"></p-menu>
</span>
<span class="hidden md:inline-flex"> <!--hidden when small screen--> <span class="hidden md:inline-flex"> <!--hidden when small screen-->
<p-buttonGroup > <p-buttonGroup >
<button type="button" pButton icon="pi pi-slack" label="Home" (click)="onHome()" <button type="button" pButton icon="pi pi-slack" label="Home" (click)="onHome()"
@@ -38,4 +36,9 @@
</div> </div>
</div> </div>
</div> </div>
<!--put in the left new row if in mobile not much room-->
<span class="md:hidden flex justify-start"> <!--hidden on md screen show on small-->
<button type="button" pButton icon="pi pi-align-justify" (click)="onemenu.toggle($event);"></button>
<p-menu #onemenu [popup]="true" [model]="oneMenu"></p-menu>
</span>
} }
+38
View File
@@ -0,0 +1,38 @@
import { HttpInterceptorFn } from '@angular/common/http';
export const credentialsInterceptor: HttpInterceptorFn = (req, next) => {
// Clone the request to add the withCredentials property
const clonedRequest = req.clone({
withCredentials: true
});
return next(clonedRequest);
};
typescriptimport { provideHttpClient, withInterceptors } from '@angular/common/http';
import { credentialsInterceptor } from './credentials.interceptor';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(
withInterceptors([credentialsInterceptor]) // Register it here
)
]
};
2. Individual Request ConfigurationIf you only want to send cookies to specific endpoints,
pass the withCredentials option directly inside your service.
typescriptimport { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class ApiService {
private http = inject(HttpClient);
getData() {
return this.http.get('https://your-api-domain.com', {
withCredentials: true // Enables cookies for this request only
});
}
}