diff --git a/src/Api/Api.csproj b/src/Api/Api.csproj index 3204b3a496..8394613c2a 100644 --- a/src/Api/Api.csproj +++ b/src/Api/Api.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index f730219c63..066c683ff4 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -14,6 +14,8 @@ using IdentityModel; using System.Globalization; using Microsoft.IdentityModel.Logging; using Microsoft.Extensions.Hosting; +using Microsoft.OpenApi.Models; +using System.Collections.Generic; namespace Bit.Api { @@ -122,7 +124,7 @@ namespace Bit.Api } }); - //services.AddSwagger(globalSettings); + services.AddSwagger(globalSettings); if(globalSettings.SelfHosted) { @@ -181,25 +183,29 @@ namespace Bit.Api app.UseEndpoints(endpoints => endpoints.MapDefaultControllerRoute()); // Add Swagger - //if(Environment.IsDevelopment() || globalSettings.SelfHosted) - //{ - // app.UseSwagger(config => - // { - // config.RouteTemplate = "specs/{documentName}/swagger.json"; - // var host = globalSettings.BaseServiceUri.Api.Replace("https://", string.Empty) - // .Replace("http://", string.Empty); - // config.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.Host = host); - // }); - // app.UseSwaggerUI(config => - // { - // config.DocumentTitle = "Bitwarden API Documentation"; - // config.RoutePrefix = "docs"; - // config.SwaggerEndpoint($"{globalSettings.BaseServiceUri.Api}/specs/public/swagger.json", - // "Bitwarden Public API"); - // config.OAuthClientId("accountType.id"); - // config.OAuthClientSecret("secretKey"); - // }); - //} + if(Environment.IsDevelopment() || globalSettings.SelfHosted) + { + app.UseSwagger(config => + { + config.RouteTemplate = "specs/{documentName}/swagger.json"; + var host = globalSettings.BaseServiceUri.Api.Replace("https://", string.Empty) + .Replace("http://", string.Empty); + config.PreSerializeFilters.Add((swaggerDoc, httpReq) => + swaggerDoc.Servers = new List + { + new OpenApiServer { Url = $"{httpReq.Scheme}://{host}" } + }); + }); + app.UseSwaggerUI(config => + { + config.DocumentTitle = "Bitwarden API Documentation"; + config.RoutePrefix = "docs"; + config.SwaggerEndpoint($"{globalSettings.BaseServiceUri.Api}/specs/public/swagger.json", + "Bitwarden Public API"); + config.OAuthClientId("accountType.id"); + config.OAuthClientSecret("secretKey"); + }); + } // Log startup logger.LogInformation(Constants.BypassFiltersEventId, globalSettings.ProjectName + " started."); diff --git a/src/Api/Utilities/ServiceCollectionExtensions.cs b/src/Api/Utilities/ServiceCollectionExtensions.cs index 2deb1c35fb..57a016125b 100644 --- a/src/Api/Utilities/ServiceCollectionExtensions.cs +++ b/src/Api/Utilities/ServiceCollectionExtensions.cs @@ -1,8 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using Bit.Core; using Microsoft.Extensions.DependencyInjection; -using Swashbuckle.AspNetCore.Swagger; +using Microsoft.OpenApi.Models; namespace Bit.Api.Utilities { @@ -12,47 +13,62 @@ namespace Bit.Api.Utilities { services.AddSwaggerGen(config => { - config.SwaggerDoc("public", new Info + config.SwaggerDoc("public", new OpenApiInfo { Title = "Bitwarden Public API", Version = "latest", - Contact = new Contact + Contact = new OpenApiContact { Name = "Bitwarden Support", - Url = "https://bitwarden.com", + Url = new Uri("https://bitwarden.com"), Email = "support@bitwarden.com" }, Description = "The Bitwarden public APIs.", - License = new License + License = new OpenApiLicense { Name = "GNU Affero General Public License v3.0", - Url = "https://github.com/bitwarden/server/blob/master/LICENSE.txt" + Url = new Uri("https://github.com/bitwarden/server/blob/master/LICENSE.txt") } }); - // config.SwaggerDoc("internal", new Info { Title = "Bitwarden Internal API", Version = "latest" }); + config.SwaggerDoc("internal", new OpenApiInfo { Title = "Bitwarden Internal API", Version = "latest" }); - config.AddSecurityDefinition("OAuth2 Client Credentials", new OAuth2Scheme + config.AddSecurityDefinition("OAuth2 Client Credentials", new OpenApiSecurityScheme { - Type = "oauth2", - Flow = "application", - TokenUrl = $"{globalSettings.BaseServiceUri.Identity}/connect/token", - Scopes = new Dictionary + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows { - { "api.organization", "Organization APIs" }, + ClientCredentials = new OpenApiOAuthFlow + { + TokenUrl = new Uri($"{globalSettings.BaseServiceUri.Identity}/connect/token"), + Scopes = new Dictionary + { + { "api.organization", "Organization APIs" }, + }, + } }, }); - config.AddSecurityRequirement(new Dictionary> + config.AddSecurityRequirement(new OpenApiSecurityRequirement { - { "OAuth2 Client Credentials", new[] { "api.organization" } } + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "OAuth2 Client Credentials" + }, + }, + new[] { "api.organization" } + } }); config.DescribeAllParametersInCamelCase(); // config.UseReferencedDefinitionsForEnums(); - var apiFilePath = Path.Combine(System.AppContext.BaseDirectory, "Api.xml"); + var apiFilePath = Path.Combine(AppContext.BaseDirectory, "Api.xml"); config.IncludeXmlComments(apiFilePath, true); - var coreFilePath = Path.Combine(System.AppContext.BaseDirectory, "Core.xml"); + var coreFilePath = Path.Combine(AppContext.BaseDirectory, "Core.xml"); config.IncludeXmlComments(coreFilePath); }); }