Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable switching to https on login page #2406

Merged
merged 11 commits into from
Sep 26, 2023
6 changes: 6 additions & 0 deletions frontend/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
"input": "node_modules/monaco-editor",
"output": "assets/monaco-editor/"
},
{
"glob": "**/*",
"input": "node_modules/@taiga-ui/icons/src",
"output": "assets/taiga-ui/icons"
},
"projects/ui/src/manifest.webmanifest",
{
"glob": "ngsw.json",
Expand All @@ -44,6 +49,7 @@
}
],
"styles": [
"node_modules/@taiga-ui/core/styles/taiga-ui-theme.less",
"projects/shared/styles/variables.scss",
"projects/shared/styles/global.scss",
"projects/shared/styles/shared.scss",
Expand Down
1 change: 1 addition & 0 deletions frontend/config-sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"mocks": {
"maskAs": "tor",
"maskAsHttps": true,
"skipStartupAlerts": true
}
},
Expand Down
26 changes: 13 additions & 13 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"monaco-editor": "^0.33.0",
"mustache": "^4.2.0",
"ng-qrcode": "^7.0.0",
"node-jose": "^2.1.1",
"node-jose": "^2.2.0",
"patch-db-client": "file: ../../../patch-db/client",
"pbkdf2": "^3.1.2",
"rxjs": "^7.5.6",
Expand Down
3 changes: 2 additions & 1 deletion frontend/projects/shared/src/services/http.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ export class HttpService {

async rpcRequest<T>(
opts: RPCOptions,
fullUrl?: string,
): Promise<LocalHttpResponse<RPCResponse<T>>> {
const { method, headers, params, timeout } = opts

return this.httpRequest<RPCResponse<T>>({
method: Method.POST,
url: this.relativeUrl,
url: fullUrl || this.relativeUrl,
headers,
body: { method, params },
timeout,
Expand Down
2 changes: 2 additions & 0 deletions frontend/projects/shared/src/types/workspace-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export type WorkspaceConfig = {
}
mocks: {
maskAs: 'tor' | 'lan'
// enables local development in secure mode
maskAsHttps: boolean
skipStartupAlerts: boolean
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,63 +15,33 @@

<!-- Installed -->
<ng-template #installed>
<!-- SECURE -->
<ng-container *ngIf="secure; else insecure">
<ng-container *ngIf="pkg | toDependencies as dependencies">
<ion-item-group *ngIf="pkg | toStatus as status">
<!-- ** status ** -->
<app-show-status
<ng-container *ngIf="pkg | toDependencies as dependencies">
<ion-item-group *ngIf="pkg | toStatus as status">
<!-- ** status ** -->
<app-show-status
[pkg]="pkg"
[dependencies]="dependencies"
[status]="status"
></app-show-status>
<!-- ** installed && !backing-up ** -->
<ng-container *ngIf="isInstalled(pkg) && !isBackingUp(status)">
<!-- ** health checks ** -->
<app-show-health-checks
*ngIf="isRunning(status)"
[pkg]="pkg"
></app-show-health-checks>
<!-- ** dependencies ** -->
<app-show-dependencies
*ngIf="dependencies.length"
[dependencies]="dependencies"
[status]="status"
></app-show-status>
<!-- ** installed && !backing-up ** -->
<ng-container *ngIf="isInstalled(pkg) && !isBackingUp(status)">
<!-- ** health checks ** -->
<app-show-health-checks
*ngIf="isRunning(status)"
[pkg]="pkg"
></app-show-health-checks>
<!-- ** dependencies ** -->
<app-show-dependencies
*ngIf="dependencies.length"
[dependencies]="dependencies"
></app-show-dependencies>
<!-- ** menu ** -->
<app-show-menu [buttons]="pkg | toButtons"></app-show-menu>
<!-- ** additional ** -->
<app-show-additional [pkg]="pkg"></app-show-additional>
</ng-container>
</ion-item-group>
</ng-container>
></app-show-dependencies>
<!-- ** menu ** -->
<app-show-menu [buttons]="pkg | toButtons"></app-show-menu>
<!-- ** additional ** -->
<app-show-additional [pkg]="pkg"></app-show-additional>
</ng-container>
</ion-item-group>
</ng-container>

<!-- INSECURE -->
<ng-template #insecure>
<ion-grid style="max-width: 540px">
<ion-row class="ion-align-items-center">
<ion-col class="ion-text-center">
<h2>
<ion-text color="warning">Http detected</ion-text>
</h2>
<p class="ion-padding-bottom">
Your connection is insecure.
<a
[routerLink]="['/system', 'root-ca']"
style="color: var(--ion-color-dark)"
>
Download and trust your server's Root CA
</a>
, then switch to https.
</p>
<ion-button (click)="launchHttps()">
Open https
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ng-template>
</ng-template>
</ion-content>
</ng-container>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'
import { ChangeDetectionStrategy, Component } from '@angular/core'
import { NavController } from '@ionic/angular'
import { PatchDB } from 'patch-db-client'
import {
Expand All @@ -13,9 +13,6 @@ import {
import { tap } from 'rxjs/operators'
import { ActivatedRoute } from '@angular/router'
import { getPkgId } from '@start9labs/shared'
import { DOCUMENT } from '@angular/common'
import { ConfigService } from 'src/app/services/config.service'
import { getServerInfo } from 'src/app/util/get-server-info'

const STATES = [
PackageState.Installing,
Expand All @@ -29,8 +26,6 @@ const STATES = [
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppShowPage {
readonly secure = this.config.isSecure()

private readonly pkgId = getPkgId(this.route)

readonly pkg$ = this.patch.watch$('package-data', this.pkgId).pipe(
Expand All @@ -44,8 +39,6 @@ export class AppShowPage {
private readonly route: ActivatedRoute,
private readonly navCtrl: NavController,
private readonly patch: PatchDB<DataModel>,
private readonly config: ConfigService,
@Inject(DOCUMENT) private readonly document: Document,
) {}

isInstalled({ state }: PackageDataEntry): boolean {
Expand All @@ -63,11 +56,4 @@ export class AppShowPage {
showProgress({ state }: PackageDataEntry): boolean {
return STATES.includes(state)
}

async launchHttps() {
const onTor = this.config.isTor()
const { 'lan-address': lanAddress, 'tor-address': torAddress } =
await getServerInfo(this.patch)
onTor ? window.open(torAddress) : window.open(lanAddress)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<ion-grid class="grid-wiz">
<img width="60px" height="60px" src="/assets/img/icon_transparent.png" />
<ion-row>
<ion-col class="ion-text-center">
<ion-icon name="lock-closed-outline" class="wiz-icon"></ion-icon>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<h2><b>Trust your Root Certificate Authority (CA)</b></h2>
<p>
Download and trust your server's Root CA to establish secure, encrypted
(
<b>HTTPS</b>
) connections with your server
</p>
</ion-col>
</ion-row>
<ion-row>
<ion-col sizeXs="12" sizeLg="4">
<div class="wiz-card">
<ion-row class="ion-justify-content-between">
<b class="wiz-step">1</b>
<tui-tooltip
content="Your server uses its Root CA to generate SSL/TLS certificates for itself and its installed services. These certificates are used to encrypt network traffic with your client devices."
direction="right"
></tui-tooltip>
</ion-row>
<div class="ion-text-center">
<h2>Download Root CA</h2>
<p>Download your server's Root CA</p>
</div>
<ion-button class="wiz-card-button" shape="round" (click)="download()">
<ion-icon slot="start" name="download-outline"></ion-icon>
Download
</ion-button>
</div>
</ion-col>
<ion-col sizeXs="12" sizeLg="4">
<div class="wiz-card" [class.disabled]="!downloadClicked">
<ion-row class="ion-justify-content-between">
<b class="wiz-step">2</b>
<tui-tooltip
content="By trusting your server's Root CA, your device can verify the authenticity of its encrypted communications with your server and installed services. You will need to trust the Root CA on every device used to connect to your server."
direction="right"
></tui-tooltip>
</ion-row>
<div class="ion-text-center">
<h2>Trust Root CA</h2>
<p>Follow instructions for your OS</p>
</div>
<ion-button
class="wiz-card-button"
shape="round"
(click)="instructions()"
[disabled]="!downloadClicked"
>
View Docs
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-button>
</div>
</ion-col>
<ion-col sizeXs="12" sizeLg="4">
<div class="wiz-card" [class.disabled]="!polling && !caTrusted">
<b class="wiz-step">3</b>
<div class="ion-text-center">
<h2>Go To Login</h2>
<p *ngIf="instructionsClicked; else space" class="inline-center">
<ion-spinner
class="wiz-spinner"
*ngIf="!caTrusted; else trusted"
></ion-spinner>
<ng-template #trusted>
<ion-icon name="ribbon-outline" color="success"></ion-icon>
</ng-template>
&nbsp;{{ caTrusted ? 'Root CA trusted!' : 'Waiting for trust...' }}
</p>
<ng-template #space>
<!-- to keep alignment -->
<p><br /></p>
</ng-template>
</div>
<ion-button
class="wiz-card-button"
shape="round"
(click)="launchHttps()"
[disabled]="!caTrusted"
>
Open
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-button>
</div>
</ion-col>
</ion-row>
<ion-row>
<ion-col class="ion-text-center">
<ion-button fill="clear" (click)="launchHttps()" [disabled]="caTrusted">
Skip
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
<a
id="install-cert"
href="/public/eos/local.crt"
[download]="document.location.hostname"
></a>
Loading
Loading