Fixed some bugs + added custom domain support
This commit is contained in:
@@ -8,19 +8,21 @@ public interface IProjectApi {
|
||||
public Project[] GetProjects(string userId);
|
||||
public Project GetProject(string projectId);
|
||||
public Task<string> AddProject(string name, string ownerId);
|
||||
public bool EditProject(string projectId, string name);
|
||||
public Task<bool> EditProject(string projectId, string name, string domain);
|
||||
public Task DeleteProject(string projectId);
|
||||
}
|
||||
|
||||
public class ProjectApi : IProjectApi {
|
||||
private readonly DatabaseContext _context;
|
||||
private readonly GeneralOptions _options;
|
||||
private readonly ProxyOptions _proxyOptions;
|
||||
private readonly IDockerApi _docker;
|
||||
private readonly IProxyApi _proxy;
|
||||
|
||||
public ProjectApi(DatabaseContext context, IOptions<GeneralOptions> options, IDockerApi docker, IProxyApi proxy) {
|
||||
public ProjectApi(DatabaseContext context, IOptions<GeneralOptions> options, IOptions<ProxyOptions> proxyOptions, IDockerApi docker, IProxyApi proxy) {
|
||||
_context = context;
|
||||
_options = options.Value;
|
||||
_proxyOptions = proxyOptions.Value;
|
||||
_docker = docker;
|
||||
_proxy = proxy;
|
||||
}
|
||||
@@ -49,12 +51,13 @@ public class ProjectApi : IProjectApi {
|
||||
Name = name,
|
||||
Port = port
|
||||
};
|
||||
project.Domain = _proxyOptions.Enable ? $"{project.ProjectId}.{_proxyOptions.Domain}" : $"{_proxyOptions.Host}:{project.Port}";
|
||||
|
||||
var container = await _docker.CreateContainer($"ghcr.io/muchobien/pocketbase:{_options.PocketBaseVersion}", port, _options.Root + project.ProjectId, $"{project.Name}_{project.ProjectId}");
|
||||
await _docker.StartContainer(container);
|
||||
project.ContainerName = container;
|
||||
|
||||
var (proxyId, certificateId) = await _proxy.AddLocation(project.ProjectId, project.Port);
|
||||
var (proxyId, certificateId) = await _proxy.AddLocation(project.Domain, project.Port);
|
||||
project.ProxyId = proxyId;
|
||||
project.CertificateId = certificateId;
|
||||
|
||||
@@ -64,13 +67,22 @@ public class ProjectApi : IProjectApi {
|
||||
return project.ProjectId;
|
||||
}
|
||||
|
||||
public bool EditProject(string projectId, string name) {
|
||||
public async Task<bool> EditProject(string projectId, string name, string domain) {
|
||||
if (name.Length > 255) return false;
|
||||
if (domain.Length > 255) return false;
|
||||
var project = GetProject(projectId);
|
||||
if (project == null) return false;
|
||||
project.Name = name;
|
||||
|
||||
if (!string.IsNullOrEmpty(domain)) {
|
||||
project.Domain = domain;
|
||||
var data = await _proxy.UpdateLocation(project);
|
||||
project.ProxyId = data.Item1;
|
||||
project.CertificateId = data.Item2;
|
||||
}
|
||||
|
||||
_context.Projects.Update(project);
|
||||
_context.SaveChanges();
|
||||
await _context.SaveChangesAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
using System.Dynamic;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ProjectManager.Backend.Entities;
|
||||
using ProjectManager.Backend.Options;
|
||||
|
||||
namespace ProjectManager.Backend.Apis;
|
||||
|
||||
public interface IProxyApi {
|
||||
public Task<(int, int)> AddLocation(string projectId, int port);
|
||||
public Task<(int, int)> AddLocation(string domain, int port);
|
||||
public Task RemoveLocation(int proxyId, int certificateId);
|
||||
public Task<(int, int)> UpdateLocation(Project project);
|
||||
}
|
||||
|
||||
public sealed class ProxyApi : IProxyApi {
|
||||
@@ -27,11 +29,11 @@ public sealed class ProxyApi : IProxyApi {
|
||||
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {response?.token}");
|
||||
}
|
||||
|
||||
public async Task<(int, int)> AddLocation(string projectId, int port) {
|
||||
public async Task<(int, int)> AddLocation(string domain, int port) {
|
||||
if (!_options.Enable) return (-1, -1);
|
||||
await Login();
|
||||
var result = await _client.PostAsJsonAsync(_options.Url + "/api/nginx/proxy-hosts",
|
||||
new CreateData($"{projectId}.{_options.Domain}", _options.Host, port, _options.Email));
|
||||
new ProxyData(domain, _options.Host, port, _options.Email));
|
||||
dynamic data = await result.Content.ReadFromJsonAsync<ExpandoObject>();
|
||||
if (data == null) return (-1, -1);
|
||||
int id = Convert.ToInt32($"{data.id}");
|
||||
@@ -46,9 +48,15 @@ public sealed class ProxyApi : IProxyApi {
|
||||
await _client.DeleteAsync(_options.Url + "/api/nginx/certificates/" + certificateId);
|
||||
}
|
||||
|
||||
public async Task<(int, int)> UpdateLocation(Project project) {
|
||||
if (!_options.Enable) return (-1, -1);
|
||||
await RemoveLocation(project.ProxyId, project.CertificateId);
|
||||
return await AddLocation(project.Domain, project.Port);
|
||||
}
|
||||
|
||||
private sealed record ProxyAuth(string identity, string secret);
|
||||
private sealed record TokenResponse(string token, string expires);
|
||||
private sealed class CreateData {
|
||||
private sealed class ProxyData {
|
||||
public string access_list_id { get; set; } = "0";
|
||||
public string advanced_config { get; set; } = " location / {\r\n proxy_pass http://%docker_ip%;\r\n proxy_hide_header X-Frame-Options;\r\n }";
|
||||
public bool allow_websocket_upgrade { get; set; } = true;
|
||||
@@ -66,7 +74,7 @@ public sealed class ProxyApi : IProxyApi {
|
||||
public bool ssl_forced { get; set; } = true;
|
||||
public SslMeta meta { get; set; }
|
||||
|
||||
public CreateData(string domain, string ip, int port, string email) {
|
||||
public ProxyData(string domain, string ip, int port, string email) {
|
||||
domain_names = new[] { domain };
|
||||
forward_host = ip;
|
||||
forward_port = port;
|
||||
|
||||
Reference in New Issue
Block a user