Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"iframe",
"iframes",
"nlog",
"webd"
"webd",
"webdirect"
]
}
62 changes: 54 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,71 @@ If your needs are simple: one solution with all hosting on a single domain, you

## Features

- Land multiple interfaces on a single site across different FileMaker Servers.
- Warn users before leaving the page that they may lose their work.
- Suppress browser back button exiting the application.
- Support for integrating browser back button into a solution to call app-specific "back button" functionality.

WebDLanding acts as a sort of reverse proxy for Web-Direct. You can create user-friendly DNS records pointed at WebDLanding and then route them, behind the scenes to the correct FileMaker Server.
- Single server and routed mode.
- Land multiple interfaces on a single site across different FileMaker Servers.

Provide a best effort to warn users that refreshing the page, or otherwise navigating away will lose their place in the web-direct application. Note: support varies by browser.

Avoid browser back button taking the user out of the solution. Provide support for solutions to listen to the native browser back button and react accordingly.

## Getting Started
WebDLanding can act as a sort of reverse proxy for Web-Direct. You can create user-friendly DNS records pointed at WebDLanding and then route them, behind the scenes to the correct FileMaker Server.

## Getting Started: Single Server Mode

You must install this project inside the FileMaker Server created website, be default located at `/FileMaker Server/HTTPServer/conf`.

### Deploy to FileMaker Server Website

1. Install ASP.NET Core Hosting Bundle.

Read about the [hosting bundle here](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/hosting-bundle?view=aspnetcore-6.0) and [download it here](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-aspnetcore-6.0.8-windows-hosting-bundle-installer).

2. Copy the release files to the FMWebSite website located at `/FileMaker Server/HTTPServer/conf`.

Copy the binaries from the release and deploy those to the directory.

3. Create user-friendly DNS records for your Web-Direct solution pointed at the server.

This must be configured in your DNS host.

4. Ensure that the FMWebSite bindings are setup to handle this DNS record.

This could be with a wildcard binding, or specific bindings. The key is that all DNS entries used are the same for both the landing (entry) and the web direct host.

5. Update `appsettings.json` to include your site(s) in the AppModels section.

```json
"AppModels": [
{
"EntryHostName": "webdirect.example.com",
"DatabaseName": "FileMakerFile",
"WebDirectHostName": "webdirect.example.com"
}
]
```

6. Modify the `web.config` file to include the ASP.NET Core hosting modules:

```xml
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\WebDLanding.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
</system.webServer>
```

## Getting Started: Pseudo Reverse Proxy Routed Mode

You must create and install this project as a separate website on a web server. It can be your FileMaker Server or a separate stand alone server. The main thing is separate DNS records.

### Install and configure WebDLanding

1. Setup the website on your web server, and copy the release files on to the website root.
2. Create a cononical WebDLanding DNS entry for hosting the application.
2. Create a canonical WebDLanding DNS entry for hosting the application.
3. Create user-friendly DNS records for your Web-Direct solutions pointed at this site.
4. Update the configuration (TODO: document options) for each site.

Expand All @@ -36,9 +82,9 @@ Update web.config in the FileMaker Server root site `/FileMaker Server/HTTPServe
<add name="Content-Security-Policy" value="frame-ancestors 'self' https://www.example.com" />
```

Replacing www.example.com with your cononical WebDLanding site from step #2 above. This allows WebDLanding to iframe in the content of the web direct session through it.
Replacing www.example.com with your cononical WebDLanding site from step #2 above. This allows WebDLanding to iframe in the content of the web direct session through it.

### Add HomeURL Support to enable iframe inception escape:
### Add HomeURL Support to enable iframe inception escape

Since the landing page uses an iframe, the native homeurl logout option will just create a loop of putting another iframe inside another iframe. This could pose challenges if a user logs in and out repeatedly. To avoid this, we use a `top.location.href` in our custom HomeURL logout page to escape to the top level.

Expand Down Expand Up @@ -152,7 +198,7 @@ Add two PreConditions which are used by both outgoing rules.
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
<add input="{URL}" pattern="^fmi/(.*)" />
<add input="{URL}" pattern="^/fmi/(.*)" />
</preCondition>
<preCondition name="NeedsRestoringAcceptEncoding">
<add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+" />
Expand Down
2 changes: 1 addition & 1 deletion src/WebDLanding/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace WebDLanding;

public class Constants
public class Globals
{
public const string BackButtonPostEventName = "BackButtonPressed";
}
48 changes: 0 additions & 48 deletions src/WebDLanding/Controllers/HomeController.cs

This file was deleted.

4 changes: 1 addition & 3 deletions src/WebDLanding/Models/AppModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ public class AppModel
public string WebDirectHostScheme { get; set; } = "https";
public string WebDirectHostName { get; set; } = default!;

private readonly string _queryString = "?homeurl=https://webdlanding.wizardsoftware.net/home/logoff";

public Uri WebDirectHostUri => new($"{WebDirectHostScheme}://{WebDirectHostName}");

public Uri WebDirectFullUri => new(
uriString: $"{WebDirectHostScheme}://{WebDirectHostName}/fmi/webd/{DatabaseName}{_queryString}"
uriString: $"{WebDirectHostScheme}://{WebDirectHostName}/fmi/webd/{DatabaseName}"
);

}
8 changes: 8 additions & 0 deletions src/WebDLanding/Models/SiteConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace WebDLanding.Models;

public class SiteConfiguration
{
public bool SingleServerMode { get; set; } = true;

public string WebdLandingMainUrl { get; set; } = string.Empty;
}
37 changes: 28 additions & 9 deletions src/WebDLanding/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,54 @@
{
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

// NLog: Setup NLog for Dependency injection
builder.Logging.ClearProviders();
builder.Host.UseNLog();

builder.Services.AddScoped<IAppModelFinder, AppSettingsAppModelFinder>();

var siteSettings = builder.Configuration.GetSection("WebDLandingConfig").Get<WebDLanding.Models.SiteConfiguration>();
builder.Services.AddSingleton(siteSettings);

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

app.UseHttpsRedirection();

// show index.html from wwwroot
app.UseDefaultFiles();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();
app.MapGet("/set-vars.js", async (IAppModelFinder finder, HttpContext context) =>
{
var model = await finder.FindByEntryHostAsync(context.Request.Host.Value);

var jsToWrite = $"let singleServerMode = {siteSettings.SingleServerMode.ToString().ToLower()};";
jsToWrite += $"let uri = '{model.WebDirectFullUri}';";
jsToWrite += $"let backEventName = '{Globals.BackButtonPostEventName}';";
var homeUri = siteSettings.SingleServerMode == true
? $"{model.EntryHostScheme}://{model.EntryHostName}"
: $"{siteSettings.WebdLandingMainUrl}";
jsToWrite += $"let homeUri = '{homeUri}';";

app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
context.Response.ContentType = "application/javascript; charset=utf-8";
await context.Response.WriteAsync(jsToWrite);
});

app.MapGet("/logoff.js", async (IAppModelFinder finder, HttpContext context) =>
{
var model = await finder.FindByEntryHostAsync(context.Request.Host.Value);
context.Response.ContentType = "application/javascript; charset=utf-8";
await context.Response.WriteAsync($"top.location.href = '{model.EntryHostUri}';");
});

app.Run();
}
Expand Down
51 changes: 0 additions & 51 deletions src/WebDLanding/Views/Home/Index.cshtml

This file was deleted.

5 changes: 0 additions & 5 deletions src/WebDLanding/Views/Home/Logoff.cshtml

This file was deleted.

28 changes: 0 additions & 28 deletions src/WebDLanding/Views/Shared/_Layout.cshtml

This file was deleted.

3 changes: 0 additions & 3 deletions src/WebDLanding/Views/_ViewImports.cshtml

This file was deleted.

3 changes: 0 additions & 3 deletions src/WebDLanding/Views/_ViewStart.cshtml

This file was deleted.

11 changes: 11 additions & 0 deletions src/WebDLanding/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
{
"WebDLandingConfig":{
"SingleServerMode": true,
"WebdLandingMainUrl": "https://webdlanding.wizardsoftware.net"
},
"AppModels": [
{
"EntryHostName": "localhost:7026",
"DatabaseName": "FileMakerFile",
"WebDirectHostName": "lade.wizardsoftware.net"
}
],
"Logging": {
"LogLevel": {
"Default": "Information",
Expand Down
Loading