diff --git a/api/Program.cs b/api/Program.cs index 548945c..cc40a4a 100644 --- a/api/Program.cs +++ b/api/Program.cs @@ -1,11 +1,30 @@ using System.Text; +using DotNetEnv; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using WinStudentGoalTracker.Api.Configuration; using WinStudentGoalTracker.Services; +Env.TraversePath().Load(); + var builder = WebApplication.CreateBuilder(args); +// Build connection string from .env variables +var dbServer = Environment.GetEnvironmentVariable("MYSQL_HOST") ?? "localhost"; +var dbPort = Environment.GetEnvironmentVariable("MYSQL_PORT") ?? "3309"; +var dbName = Environment.GetEnvironmentVariable("MYSQL_DATABASE") ?? "winstudentgoaltracker"; +var dbUser = Environment.GetEnvironmentVariable("MYSQL_USER") ?? "root"; +var dbPassword = Environment.GetEnvironmentVariable("MYSQL_PASSWORD") ?? ""; +builder.Configuration["ConnectionStrings:DefaultConnection"] = + $"Server={dbServer};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};"; + +// Override JWT key from .env if present +var envJwtKey = Environment.GetEnvironmentVariable("JWT_KEY"); +if (!string.IsNullOrEmpty(envJwtKey)) + builder.Configuration["Jwt:Key"] = envJwtKey; + +Console.WriteLine($"Built connection string from .env: {builder.Configuration["ConnectionStrings:DefaultConnection"]}"); + ConfigHelper.Configuration = builder.Configuration; var jwtKey = builder.Configuration["Jwt:Key"] ?? "super_secret_key_change_me_in_production_123!"; @@ -49,7 +68,32 @@ builder.Services.AddHttpClient(client => builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); +builder.Services.AddSwaggerGen(c => +{ + c.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme + { + Name = "Authorization", + Type = Microsoft.OpenApi.Models.SecuritySchemeType.Http, + Scheme = "bearer", + BearerFormat = "JWT", + In = Microsoft.OpenApi.Models.ParameterLocation.Header, + Description = "Enter your JWT token (without 'Bearer ' prefix)." + }); + c.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement + { + { + new Microsoft.OpenApi.Models.OpenApiSecurityScheme + { + Reference = new Microsoft.OpenApi.Models.OpenApiReference + { + Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme, + Id = "Bearer" + } + }, + Array.Empty() + } + }); +}); builder.Services.AddCors(options => { options.AddDefaultPolicy(policy => diff --git a/api/api.csproj b/api/api.csproj index ab39f78..4c9f483 100644 --- a/api/api.csproj +++ b/api/api.csproj @@ -8,6 +8,7 @@ + diff --git a/api/appsettings.Development.json b/api/appsettings.Development.json index cee8d31..0c208ae 100644 --- a/api/appsettings.Development.json +++ b/api/appsettings.Development.json @@ -1,7 +1,4 @@ { - "ConnectionStrings": { - "DefaultConnection": "Server=localhost;Port=3306;Database=winstudentgoaltracker;Uid=root;Pwd=change_me;" - }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/api/appsettings.json b/api/appsettings.json index 2276e9d..75f89c2 100644 --- a/api/appsettings.json +++ b/api/appsettings.json @@ -1,9 +1,9 @@ { "ConnectionStrings": { - "DefaultConnection": "Server=localhost;Port=3306;Database=winstudentgoaltracker;Uid=root;Pwd=change_me;" + "DefaultConnection": "Set via MYSQL_HOST, MYSQL_PORT, MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD in .env" }, "Jwt": { - "Key": "super_secret_key_change_me_in_production_123!", + "Key": "Set via JWT_KEY in .env", "Issuer": "WinStudentGoalTrackerAPI" }, "Ollama": { diff --git a/api/src/Controllers/StudentController.cs b/api/src/Controllers/StudentController.cs index 1cac137..1eedef6 100644 --- a/api/src/Controllers/StudentController.cs +++ b/api/src/Controllers/StudentController.cs @@ -19,6 +19,14 @@ public class StudentController : BaseController [ProducesResponseType(typeof(ResponseResult>), StatusCodes.Status200OK)] public async Task>>> GetAll() { + + var (userId, email, programId, role, error) = GetProgramUserFromClaims(); + + if (error is not null) + { + return error; + } + var students = await _studentRepository.GetAllAsync(); var response = students.Select(StudentResponse.FromDatabaseModel); diff --git a/api/src/DataAccess/Repositories/AuthRepository.cs b/api/src/DataAccess/Repositories/AuthRepository.cs index 85ad5f9..742e2a5 100644 --- a/api/src/DataAccess/Repositories/AuthRepository.cs +++ b/api/src/DataAccess/Repositories/AuthRepository.cs @@ -19,7 +19,7 @@ public class AuthRepository string? userAgent) { using var db = Connection; - var result = await db.QuerySingleOrDefaultAsync( + var result = await db.QuerySingleOrDefaultAsync( "sp_RefreshToken_Create", new { @@ -33,7 +33,7 @@ public class AuthRepository p_user_agent = userAgent }, commandType: CommandType.StoredProcedure); - return result != null ? Guid.Parse(result) : null; + return result; } public async Task GetRefreshTokenByIdAsync(Guid refreshTokenId)