mirror of
https://github.com/sandstorm-io/sandstorm.git
synced 2026-11-07 10:02:45 -05:00
465 lines
17 KiB
HTML
465 lines
17 KiB
HTML
<!--
|
|
Sandstorm - Personal Cloud Sandbox
|
|
Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors
|
|
All rights reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
-->
|
|
|
|
<template name="layout">
|
|
{{>sandstormTopbar globalTopbar}}
|
|
|
|
{{#with demoExpired}}
|
|
{{>title (_ "shell.layout.demoExpired.title")}}
|
|
|
|
<div id="demo-expired" class="demo-expired-main-content {{#if hideNavbar}}hide-navbar{{else}}{{#if shrinkNavbar}}shrink-navbar{{/if}}{{/if}}">
|
|
<h1>{{_ "shell.layout.demoExpired.title"}}</h1>
|
|
{{#if canUpgradeDemo}}
|
|
<p>{{_ "shell.layout.demoExpired.canUpgrade"}}</p>
|
|
<div class="login">
|
|
{{> loginButtonsDialog accountsUi=globalAccountsUi}}
|
|
</div>
|
|
{{else}}
|
|
<p>{{_ "shell.layout.demoExpired.cannotUpgrade"}}
|
|
<form class="standard-form">
|
|
<div class="button-row">
|
|
<button name="logout" type="submit">{{_ "shell.layout.demoExpired.signOut"}}</button>
|
|
</div>
|
|
</form>
|
|
</p>
|
|
{{/if}}
|
|
</div>
|
|
{{else}}
|
|
{{#if credentialUser}}
|
|
{{> credentialLoginInterstitial grains=globalGrains}}
|
|
{{else}}
|
|
{{#if isAccountSuspended}}
|
|
<div class="suspended-main-content {{#if hideNavbar}}hide-navbar{{else}}{{#if shrinkNavbar}}shrink-navbar{{/if}}{{/if}}">
|
|
{{> accountSuspended }}
|
|
</div>
|
|
{{else}}
|
|
{{#if firstLogin}}
|
|
<div class="first-sign-in-main-content {{#if hideNavbar}}hide-navbar{{else}}{{#if shrinkNavbar}}shrink-navbar{{/if}}{{/if}}">
|
|
{{> sandstormAccountsFirstSignIn accountSettingsUi}}
|
|
</div>
|
|
{{else}}
|
|
|
|
{{!-- standard topbar items --}}
|
|
{{#sandstormTopbarItem name="home-button" topbar=globalTopbar}}
|
|
<a href="/">{{effectiveServerTitle}}</a>
|
|
{{/sandstormTopbarItem}}
|
|
{{#if showAccountButtons}}
|
|
{{>sandstormTopbarItem name="account" topbar=globalTopbar data=accountButtonsData
|
|
template="accountButtons" popupTemplate="accountButtonsPopup"}}
|
|
{{else}}
|
|
{{>sandstormTopbarItem name="login" topbar=globalTopbar data=globalAccountsUi
|
|
template="loginButtons" popupTemplate="loginButtonsPopup"}}
|
|
{{/if}}
|
|
{{#if currentUser}}
|
|
{{>sandstormTopbarItem name="notifications" topbar=globalTopbar
|
|
template="notifications" popupTemplate="notificationsPopup"
|
|
priority=-1}}
|
|
{{/if}}
|
|
{{!-- admin alerts --}}
|
|
{{#with adminAlert}}
|
|
{{#if adminAlertIsTooLarge}}
|
|
{{#sandstormTopbarItem name="admin-alert" topbar=globalTopbar priority=-2}}
|
|
{{!-- TODO(cleaup): Awkwardly, the event handlers on Template.layout actually work
|
|
on this topbar item solely because the whole topbar itself is embedded inside the
|
|
"layout" template. But, we shouldn't be relying on that! Move this to its own
|
|
template... --}}
|
|
<span id="admin-alert-icon" class="{{className}}">{{_ "shell.layout.adminAlert.icon"}}</span>
|
|
{{else}}
|
|
<h4>{{_ "shell.layout.adminAlert.title"}}</h4>
|
|
<p>
|
|
{{#if alertUrl}}
|
|
<a href="{{alertUrl}}" class="alert {{className}}">{{text}}</a>
|
|
{{else}}
|
|
<span class="alert {{className}}">{{text}}</span>
|
|
{{/if}}
|
|
</p>
|
|
{{/sandstormTopbarItem}}
|
|
{{else}}
|
|
{{#sandstormTopbarItem name="admin-alert" topbar=globalTopbar}}
|
|
{{#if alertUrl}}
|
|
<a href="{{alertUrl}}" class="alert {{className}}">{{text}}</a>
|
|
{{else}}
|
|
<span class="alert {{className}}">{{text}}</span>
|
|
{{/if}}
|
|
{{/sandstormTopbarItem}}
|
|
{{/if}}
|
|
{{/with}}
|
|
|
|
{{#with billingPromptState}}
|
|
{{> Template.dynamic template=billingPromptTemplate}}
|
|
{{/with}}
|
|
|
|
{{/if}} {{!-- firstLogin --}}
|
|
{{/if}} {{!-- isAccountSuspended --}}
|
|
{{/if}} {{!-- credentialUser --}}
|
|
{{/with}} {{!-- demoExpired --}}
|
|
|
|
{{!-- Make sure to always render the main-content div, but only yield if there is no interstitial
|
|
to render on top. The main-content div needs to be stable so that any GrainView that gets
|
|
attached does not get orphaned. For example, if the main-content div were inside the
|
|
{{#if firstLogin}} block, then grain views could appear to become blanked out when a demo
|
|
user upgrades to a real account by linking an email identity.
|
|
--}}
|
|
<div class="main-content{{#if hideNavbar}} hide-navbar{{else}}{{#if shrinkNavbar}} shrink-navbar{{/if}}{{/if}}{{#if isStandalone}} standalone{{/if}}">
|
|
{{#unless demoExpired}}
|
|
{{#unless credentialUser}}
|
|
{{#unless firstLogin}}
|
|
{{> desktopNotifications "" }}
|
|
{{> yield}}
|
|
{{/unless}}
|
|
{{/unless}}
|
|
{{/unless}}
|
|
</div>
|
|
|
|
{{#with demoModal}}
|
|
{{#modalDialogWithBackdrop onDismiss=dismissDemoModal class="demo-startup-modal"}}
|
|
<div class="top">
|
|
<p class="header">{{_ "shell.layout.demoModal.header"}}</p>
|
|
<p class="body">
|
|
{{#if appdemo}}
|
|
{{_ "shell.layout.demoModal.withAppDemo" appdemo}}
|
|
{{else}}
|
|
{{_ "shell.layout.demoModal.withoutAppDemo"}}
|
|
{{/if}}</p>
|
|
|
|
<button class="button-primary start">
|
|
{{#if appdemo}}
|
|
{{_ "shell.layout.demoModal.startButton.withAppDemo" appdemo}}
|
|
{{else}}
|
|
{{_ "shell.layout.demoModal.startButton.withoutAppDemo"}}
|
|
{{/if}}
|
|
</button>
|
|
|
|
</div>
|
|
<div class="bottom">
|
|
{{{_ "shell.layout.demoModal.explanation"}}}
|
|
{{{_ "shell.layout.demoModal.securityOverview"}}}
|
|
</div>
|
|
{{/modalDialogWithBackdrop}}
|
|
{{/with}}
|
|
</template>
|
|
|
|
<template name="noLayout">
|
|
{{!-- An empty layout for resource windows e.g. grainLog that we want to put reactive stuff in,
|
|
but don't need the topbar and reload blocking and other fanciness that the layout gives --}}
|
|
{{> yield}}
|
|
</template>
|
|
|
|
<template name="notifications">
|
|
<button class="show-popup icon icon-notification" title="{{_ "shell.notifications.hint"}}">
|
|
{{#if notificationCount}}
|
|
<span class="count">{{notificationCount}}</span>
|
|
{{/if}}
|
|
{{!-- HACK: If we don't have whitespace before the string "Notifications", the 'N' will be
|
|
visible next to the bell. This used to not be a problem before i18n, because there was
|
|
whitespace in the literal text, but now it's a template expansion and blaze slurps the
|
|
whitespace.
|
|
TODO(cleanup): Why on Earth is this text visible in the fist place? --}}
|
|
<span> </span>
|
|
{{_ "shell.notifications.text"}}
|
|
</button>
|
|
</template>
|
|
|
|
<template name="notificationsPopup">
|
|
<h4>{{_ "shell.notificationsPopup.title"}}</h4>
|
|
<ul class="notification-list">
|
|
{{#each notifications}}
|
|
<li>
|
|
{{> notificationItem .}}
|
|
</li>
|
|
{{else}}
|
|
<li>{{_ "shell.notificationsPopup.empty"}}</li>
|
|
{{/each}}
|
|
</ul>
|
|
</template>
|
|
|
|
<template name="title">
|
|
{{#sandstormTopbarItem name="title" priority=5 topbar=globalTopbar}}{{.}}{{/sandstormTopbarItem}}
|
|
</template>
|
|
|
|
<template name="loading">
|
|
{{>title (_ "shell.loading.title")}}
|
|
<div class="centered-box">{{_ "shell.loading.text"}}</div>
|
|
</template>
|
|
|
|
<template name="loadingNoMessage">
|
|
{{!-- When switching between grains, we don't really want to show a "loading..." message until
|
|
the grain's subscriptions are ready, since we've already loaded the iframe and the user can be
|
|
interacting with it immediately. But we also want to use waitOn for the topbar items. So we
|
|
set a loading template that is effectively empty string, and everything is great. --}}
|
|
</template>
|
|
|
|
<template name="notFound">
|
|
{{>title (_ "shell.notFound.title")}}
|
|
<div class="centered-box">{{_ "shell.notFound.text"}}</div>
|
|
</template>
|
|
|
|
<template name="root">
|
|
<div id="intro" class="{{#if splashUrl}}has-splash{{/if}}">
|
|
{{> loginButtonsDialog accountsUi=globalAccountsUi}}
|
|
{{#if splashUrl}}
|
|
<iframe src="{{splashUrl}}"></iframe>
|
|
{{/if}}
|
|
</div>
|
|
</template>
|
|
|
|
<template name="apps">
|
|
{{> sandstormAppListPage . }}
|
|
</template>
|
|
|
|
<template name="grains">
|
|
{{> sandstormGrainListPage . }}
|
|
</template>
|
|
|
|
<template name="appDetails">
|
|
{{> sandstormAppDetailsPage . }}
|
|
</template>
|
|
|
|
<template name="grainLogContents">
|
|
<pre>{{_ "shell.grainLogContents.prefix"}}{{{logHtml}}}</pre>
|
|
</template>
|
|
|
|
<template name="grainLog">
|
|
<div class="grainlog-title">{{_ "shell.grainLog.title" title}}</div>
|
|
<div class="grainlog-contents" aria-live="polite">
|
|
{{> grainLogContents logHtml=html onRenderedHook=maybeScrollToBottom }}
|
|
</div>
|
|
</template>
|
|
|
|
<template name="install">
|
|
{{> sandstormAppInstallPage . }}
|
|
</template>
|
|
|
|
<template name="account">
|
|
{{!-- Data context is an instance of SandstormAccountSettingsUi --}}
|
|
<div class="account">
|
|
{{#if .}}
|
|
{{>sandstormAccountSettings .}}
|
|
{{/if}}
|
|
</div>
|
|
</template>
|
|
|
|
<template name="signup">
|
|
{{>title (_ "shell.signup.title")}}
|
|
|
|
<div class="centered-box">
|
|
{{#if alreadySignedUp}}
|
|
{{#if keyIsUsed}}
|
|
<p>{{{_ "shell.signup.signedUp.keyIsUsedWithOrigin" appMarketUrl origin}}}</p>
|
|
{{else}}
|
|
<p>{{_ "shell.signup.signedUp.keyIsNotUsed"}}</p>
|
|
{{/if}}
|
|
{{else}}
|
|
{{#if keyIsValid}}
|
|
{{#if keyIsUsed}}
|
|
<p>{{_ "shell.signup.keyIsUsed"}}</p>
|
|
{{else}}
|
|
{{#if currentUser}}
|
|
<p>{{_ "shell.signup.processing"}}</p>
|
|
{{else}}
|
|
<p>{{signupDialog}} {{_ "shell.signup.signInGuide"}}</p>
|
|
<div id="sign-in-arrow"></div>
|
|
{{/if}}
|
|
{{/if}}
|
|
{{else}}
|
|
<p>{{_ "shell.signup.invalidKey"}}</p>
|
|
{{/if}}
|
|
{{/if}}
|
|
</div>
|
|
</template>
|
|
|
|
<template name="uploadStatus">
|
|
{{>title (_ "shell.uploadStatus.title")}}
|
|
|
|
<div id="restoreGrain" class="centered-box">
|
|
{{#if error}}
|
|
<p>{{_ "shell.uploadStatus.uploadFailedWithError" error.status error.statusText}}</p>
|
|
<pre>{{error.response}}</pre>
|
|
{{else}}
|
|
{{#if status}}
|
|
<p>
|
|
{{#if progress}}
|
|
{{_ "shell.uploadStatus.statusWithProgress" status progress}}
|
|
{{else}}
|
|
{{_ "shell.uploadStatus.status" status}}
|
|
{{/if}}
|
|
</p>
|
|
{{else}}
|
|
<p>{{_ "shell.uploadStatus.uploadFailed"}}</p>
|
|
{{/if}}
|
|
{{/if}}
|
|
</div>
|
|
</template>
|
|
|
|
<template name="uploadTest">
|
|
{{>title (_ "shell.uploadTest.title")}}
|
|
|
|
<p>{{_ "shell.uploadTest.explanation"}}</p>
|
|
|
|
<p>{{_ "shell.uploadTest.uploadApp"}} <input type="file" id="upload-app"></p>
|
|
<p>{{_ "shell.uploadTest.uploadBackup"}} <input type="file" id="upload-backup"></p>
|
|
</template>
|
|
|
|
<template name="referrals">
|
|
{{#if referralsEnabled}}
|
|
{{>title (_ "shell.referrals.title")}}
|
|
{{setDocumentTitle}}
|
|
<div class="referrals">
|
|
<h1>{{_ "shell.referrals.title"}}</h1>
|
|
<header>
|
|
<h2>{{{_ "shell.referrals.header.isPaid.title"}}}</h2>
|
|
|
|
<p>{{_ "shell.referrals.header.isPaid.explanation"}}</p>
|
|
</header>
|
|
<section>
|
|
<h1>{{_ "shell.referrals.howTo.title"}}</h1>
|
|
<p>{{_ "shell.referrals.howTo.explanation"}}</p>
|
|
|
|
<div class="image-tutorial">
|
|
<ol>
|
|
<li>{{_ "shell.referrals.howTo.getStart.step1"}}
|
|
<img src="/referral-graphics/referral-1.svg">
|
|
</li>
|
|
<li>{{_ "shell.referrals.howTo.getStart.step2"}}
|
|
<img src="/referral-graphics/referral-2.svg">
|
|
</li>
|
|
<li>{{_ "shell.referrals.howTo.getStart.step3"}}
|
|
<img src="/referral-graphics/referral-3.svg">
|
|
</li>
|
|
</ol>
|
|
|
|
</div>
|
|
|
|
{{#if currentUser}}
|
|
<h2>{{_ "shell.referrals.status.title"}}</h2>
|
|
|
|
<p>{{_ "shell.referrals.status.explanation"}}</p>
|
|
|
|
{{#with notYetCompleteReferralNames}}{{#if this.count}}
|
|
<h3>{{_ "shell.referrals.status.pending.title"}}</h3>
|
|
|
|
<p class="gentle-hint">{{_ "shell.referrals.status.pending.explanation"}}</p>
|
|
|
|
<ul class="comma-separated-ul">
|
|
{{#each this}}
|
|
<li>{{name}}</li>
|
|
{{/each}}
|
|
</ul>
|
|
|
|
{{/if}}{{/with}}
|
|
|
|
{{#with completeReferralNames}}{{#if this.count}}
|
|
<h3>{{_ "shell.referrals.status.success.title"}}</h3>
|
|
|
|
<p class="gentle-hint">{{_ "shell.referrals.status.success.explanation"}}</p>
|
|
|
|
<ul class="comma-separated-ul">
|
|
{{#each this}}
|
|
<li>{{name}}</li>
|
|
{{/each}}
|
|
</ul>
|
|
|
|
{{/if}}{{/with}}
|
|
|
|
<h2 class="fine-print">{{_ "shell.referrals.finePrint.title"}}</h2>
|
|
|
|
<p>{{{_ "shell.referrals.finePrint.warningWithAccountLink" (pathFor route='account')}}}</p>
|
|
|
|
<p>{{_ "shell.referrals.finePrint.explanation"}}</p>
|
|
|
|
{{/if}}
|
|
</section>
|
|
</div>
|
|
{{/if}}
|
|
</template>
|
|
|
|
<template name="about">
|
|
{{setDocumentTitle}}
|
|
{{>title (_ "shell.about.title")}}
|
|
|
|
<div class="about">
|
|
<h1>{{_ "shell.about.title"}}</h1>
|
|
|
|
<section class="intro">
|
|
<p>{{{_ "shell.about.intro.explanation"}}}</p>
|
|
|
|
<p class="version">{{_ "shell.about.intro.version" build}}</p>
|
|
{{#if isUnofficial}}
|
|
<p class="unofficial">{{{_ "shell.about.intro.unofficialWarning"}}}</p>
|
|
{{/if}}
|
|
</section>
|
|
|
|
<section class="changelog">
|
|
<h2>{{_ "shell.about.changelog.title"}}</h2>
|
|
|
|
{{> changelog ""}}
|
|
</section>
|
|
|
|
<section class="dependencies">
|
|
<h2>{{_ "shell.about.dependencies.title"}}</h2>
|
|
<ul>
|
|
<!-- TODO(soon): This list has a lot missing. Review. -->
|
|
<li><a href="http://nodejs.org/">Node.js</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://www.meteor.com/">Meteor web framework</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://letsencrypt.org/">Let's Encrypt</a> (external service)</li>
|
|
<li><a href="https://github.com/jedisct1/libsodium">libsodium</a> (ISC {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://boringssl.googlesource.com/boringssl/">BoringSSL</a> (OpenSSL {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/seccomp/libseccomp">libseccomp</a> (LGPL {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://www.mongodb.org/">MongoDB</a> (SSPL)</li>
|
|
<li><a href="https://github.com/EventedMind/iron-router">Iron Router</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="http://underscorejs.org/">Underscore.js</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="http://www.senchalabs.org/connect/">Connect middleware</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://www.google.com/fonts/specimen/Source+Sans+Pro">Source Sans Pro font</a> (SIL OFL)</li>
|
|
<li><a href="https://github.com/joyent/http-parser">Node/nginx HTTP parser library</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/andris9/simplesmtp">Simple SMTP by Andris Reinman</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/drudru/ansi_up">ansi_up library by Dru Nelson</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/stewartlord/identicon.js">identicon.js by Stewart Lord</a> (BSD {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/usablica/intro.js">intro.js by Afshin Mehrabani</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/panva/node-openid-client">node-openid-client by Filip Skokan</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://git.rootprojects.org/root/acme.js.git">ACME.js by Root / AJ ONeal</a> (MPL)</li>
|
|
<li><a href="https://github.com/nodecraft/acme-dns-01-cloudflare">ACME.js Cloudflare plugin by Nodecraft</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/rs22/acme-dns-01-desec">ACME.js deSEC plugin by Robert Schmid</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://github.com/latacora/acme-dns-01-gcp">ACME.js GCP plugin by Latacora</a> (MPL)</li>
|
|
<li><a href="https://git.y.gy/firstdorsal/acme-dns-01-powerdns">ACME.js PowerDNS plugin by Paul Colin Hennig</a> (MIT {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="http://libb64.sourceforge.net/">libb64 by Chris Venter</a> (Public Domain)</li>
|
|
<li><a href="http://tukaani.org/xz/">XZ Utils</a> (Public Domain / GPL)</li>
|
|
<li><a href="http://www.info-zip.org/">Info-ZIP</a> (Info-ZIP {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="http://www.gnu.org/software/libc/libc.html">GNU C library</a> (LGPL {{_ "shell.about.dependencies.license"}})</li>
|
|
<li><a href="https://gcc.gnu.org/libstdc++/">GNU C++ Library</a> (LGPL {{_ "shell.about.dependencies.license"}})</li>
|
|
<li class="spacer"> </li>
|
|
<li class="spacer"> </li>
|
|
<li class="spacer"> </li>
|
|
</ul>
|
|
<p>{{_ "shell.about.dependencies.explanation"}}</p>
|
|
</section>
|
|
|
|
<section class="copyright">
|
|
<h2>{{_ "shell.about.copyright.title"}}</h2>
|
|
<p>{{_ "shell.about.copyright.license"}}</p>
|
|
</section>
|
|
|
|
<section class="terms">
|
|
<ul>
|
|
<li><a href="https://github.com/sandstorm-io/sandstorm/blob/master/LICENSE">{{_ "shell.about.terms.license"}}</a></li>
|
|
{{#with termsUrl}}<li><a href="{{.}}">{{_ "shell.about.terms.terms"}}</a></li>{{/with}}
|
|
{{#with privacyUrl}}<li><a href="{{.}}">{{_ "shell.about.terms.privacy"}}</a></li>{{/with}}
|
|
</ul>
|
|
</section>
|
|
</div>
|
|
</template>
|