reauth and terms:
- use modal display from sw message to request auth, as redirect may be on a non-html page - also use modal for terms to avoid leaving page
This commit is contained in:
Vendored
+63
-37
File diff suppressed because one or more lines are too long
+85
-66
@@ -56,7 +56,6 @@ class AppMain extends LitElement
|
|||||||
navMenuShown: { type: Boolean },
|
navMenuShown: { type: Boolean },
|
||||||
showTerms: { type: Boolean },
|
showTerms: { type: Boolean },
|
||||||
sourceLoaded: { type: Boolean },
|
sourceLoaded: { type: Boolean },
|
||||||
gdriveReAuth: { type: String }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +73,6 @@ class AppMain extends LitElement
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
${!this.gdriveReAuth ? html`
|
|
||||||
<div class="container" style="display: sticky">
|
<div class="container" style="display: sticky">
|
||||||
<nav class="navbar breadcrumbs" role="navigation" aria-label="main navigation">
|
<nav class="navbar breadcrumbs" role="navigation" aria-label="main navigation">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
@@ -97,44 +95,37 @@ class AppMain extends LitElement
|
|||||||
</div>` : html``}
|
</div>` : html``}
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
<a href="?terms" class="navbar-item">Terms</a>
|
<a href="?terms" @click="${(e) => { e.preventDefault(); this.showTerms = true} }"class="navbar-item">Terms</a>
|
||||||
<a href="/docs" class="navbar-item">
|
<a href="/docs" target="_blank" class="navbar-item">
|
||||||
<fa-icon .svg="${fasHelp}"></fa-icon> Docs
|
<fa-icon .svg="${fasHelp}"></fa-icon> Docs
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>` : html``}
|
</div>
|
||||||
${this.renderContent()}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderContent() {
|
${this.sourceUrl ? html`
|
||||||
if (this.gdriveReAuth) {
|
|
||||||
return html`
|
|
||||||
<div class="hero is-fullheight">
|
|
||||||
<div class="hero-body">
|
|
||||||
<div class="container has-text-centered">
|
|
||||||
<wr-gdrive .fileId=${this.gdriveReAuth} .reauth="${true}" @load-ready=${this.onReAuthed}/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
} else if (this.sourceUrl) {
|
|
||||||
return html`
|
|
||||||
<wr-coll .loadInfo="${this.loadInfo}"
|
<wr-coll .loadInfo="${this.loadInfo}"
|
||||||
sourceUrl="${this.sourceUrl}"
|
sourceUrl="${this.sourceUrl}"
|
||||||
@replay-favicons=${this.onFavIcons}
|
@replay-favicons=${this.onFavIcons}
|
||||||
@coll-loaded=${this.onCollLoaded}></wr-coll>
|
@coll-loaded=${this.onCollLoaded}></wr-coll>
|
||||||
`;
|
` : html`
|
||||||
} else if (this.showTerms) {
|
<wr-index @load-start=${this.onStartLoad}></wr-index>
|
||||||
return html`
|
`}
|
||||||
|
${this.showTerms ? html`
|
||||||
|
<div class="modal is-active">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<p class="modal-card-title">Terms and Privacy</p>
|
||||||
|
<button class="delete" aria-label="close" @click="${(e) => this.showTerms = false}"></button>
|
||||||
|
</header>
|
||||||
|
<section class="modal-card-body">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3 class="title">Terms</h3>
|
|
||||||
<p>This site is a static browser-based application that loads web archive files provided by the user
|
<p>This site is a static browser-based application that loads web archive files provided by the user
|
||||||
and renders them for replay in the browser.</p>
|
and renders them for replay in the browser.</p>
|
||||||
<p>The site is operated by the <a href="https://webrecorder.net/">Webrecorder Project</a></p>
|
<p>The site is operated by the <a href="https://webrecorder.net/">Webrecorder Project</a></p>
|
||||||
<p>See the <a href="/docs">About</a> for more info on how it works.</p>
|
<p>See the <a target="_blank" href="/docs">Docs</a> for more info on how it works.</p>
|
||||||
|
|
||||||
<h3>Privacy</h3>
|
<h3>Privacy</h3>
|
||||||
<p><b>No data is uploaded anywhere and no information is collected.</b></p>
|
<p><b>No data is uploaded anywhere and no information is collected.</b></p>
|
||||||
@@ -147,15 +138,14 @@ class AppMain extends LitElement
|
|||||||
AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
|
AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
|
||||||
INCLUDING WITHOUT LIMITATION ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
INCLUDING WITHOUT LIMITATION ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
</p>
|
</p>
|
||||||
<a class="button is-primary" href="#" @click="${(e) => window.history.back()}">Back</a>
|
<a class="button is-primary" href="#" @click="${(e) => this.showTerms = false}">Close</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
</section>
|
||||||
} else if (this.sourceUrl === "") {
|
</div>
|
||||||
return html`
|
<button class="modal-close is-large" aria-label="close"></button>
|
||||||
<wr-index @load-start=${this.onStartLoad}></wr-index>
|
</div>
|
||||||
`;
|
` : ``} `
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
@@ -168,22 +158,6 @@ class AppMain extends LitElement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onReAuthed(event) {
|
|
||||||
const redir = this.pageParams.get("redirUrl");
|
|
||||||
const {coll} = await sourceToId(this.sourceUrl);
|
|
||||||
|
|
||||||
const headers = event.detail.headers;
|
|
||||||
|
|
||||||
const resp = await fetch(`/wabac/api/${coll}/updateAuth`, {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({headers})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (redir) {
|
|
||||||
window.location.href = redir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onFavIcons(event) {
|
onFavIcons(event) {
|
||||||
const head = document.querySelector('head');
|
const head = document.querySelector('head');
|
||||||
const oldLinks = document.querySelectorAll("link[rel*='icon']");
|
const oldLinks = document.querySelectorAll("link[rel*='icon']");
|
||||||
@@ -225,11 +199,6 @@ class AppMain extends LitElement
|
|||||||
|
|
||||||
this.sourceUrl = this.pageParams.get("source") || "";
|
this.sourceUrl = this.pageParams.get("source") || "";
|
||||||
|
|
||||||
//todo: make more generic?
|
|
||||||
if (this.pageParams.get("autherr") && this.pageParams.get("redirUrl") && this.sourceUrl.startsWith("googledrive://")) {
|
|
||||||
this.gdriveReAuth = this.sourceUrl.slice("googledrive://".length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.pageParams.has("terms")) {
|
if (this.pageParams.has("terms")) {
|
||||||
this.showTerms = true;
|
this.showTerms = true;
|
||||||
}
|
}
|
||||||
@@ -333,7 +302,6 @@ class WrLoader extends LitElement
|
|||||||
switch (scheme) {
|
switch (scheme) {
|
||||||
case "googledrive":
|
case "googledrive":
|
||||||
this.state = "googledrive";
|
this.state = "googledrive";
|
||||||
this.fileId = host;
|
|
||||||
source = await this.googledriveInit();
|
source = await this.googledriveInit();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -442,7 +410,7 @@ class WrLoader extends LitElement
|
|||||||
renderContent() {
|
renderContent() {
|
||||||
switch (this.state) {
|
switch (this.state) {
|
||||||
case "googledrive":
|
case "googledrive":
|
||||||
return html`<wr-gdrive .fileId=${this.fileId} @load-ready=${this.onLoadReady}/>`
|
return html`<wr-gdrive .sourceId=${this.sourceUrl} @load-ready=${this.onLoadReady}/>`
|
||||||
|
|
||||||
case "started":
|
case "started":
|
||||||
return html`
|
return html`
|
||||||
@@ -1376,6 +1344,8 @@ class WrReplayPage extends LitElement
|
|||||||
this.url = "";
|
this.url = "";
|
||||||
this.ts = "";
|
this.ts = "";
|
||||||
this.title = "";
|
this.title = "";
|
||||||
|
|
||||||
|
this.authNeeded = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@@ -1392,12 +1362,19 @@ class WrReplayPage extends LitElement
|
|||||||
title: { type: String },
|
title: { type: String },
|
||||||
|
|
||||||
iframeUrl: { type: String },
|
iframeUrl: { type: String },
|
||||||
isLoading: { type: Boolean }
|
isLoading: { type: Boolean },
|
||||||
|
|
||||||
|
authNeeded: { type: Object }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
window.addEventListener("message", (event) => this.onReplayMessage(event));
|
window.addEventListener("message", (event) => this.onReplayMessage(event));
|
||||||
|
navigator.serviceWorker.addEventListener("message", (event) => {
|
||||||
|
if (event.data.type === "authneeded") {
|
||||||
|
this.authNeeded = event.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
doSetIframeUrl() {
|
doSetIframeUrl() {
|
||||||
@@ -1456,9 +1433,12 @@ class WrReplayPage extends LitElement
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onRefresh(event) {
|
onRefresh(event, forceReload) {
|
||||||
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (this.isLoading) {
|
}
|
||||||
|
|
||||||
|
if (this.isLoading && !forceReload) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1513,6 +1493,11 @@ class WrReplayPage extends LitElement
|
|||||||
#refresh {
|
#refresh {
|
||||||
border: 0px;
|
border: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
top: 174px;
|
||||||
|
}
|
||||||
|
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1546,8 +1531,43 @@ class WrReplayPage extends LitElement
|
|||||||
<iframe @message="${this.onReplayMessage}"
|
<iframe @message="${this.onReplayMessage}"
|
||||||
src="${this.iframeUrl}"></iframe>
|
src="${this.iframeUrl}"></iframe>
|
||||||
` : ``}
|
` : ``}
|
||||||
|
|
||||||
|
${this.authNeeded ? html`
|
||||||
|
<div class="modal is-active">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<p class="modal-card-title">Auth Needed</p>
|
||||||
|
<button class="delete" aria-label="close" @click="${(e) => this.authNeeded = null}"></button>
|
||||||
|
</header>
|
||||||
|
<section class="modal-card-body">
|
||||||
|
<div class="container has-text-centered">
|
||||||
|
<wr-gdrive .sourceId=${this.authNeeded.source} .reauth="${true}" @load-ready=${this.onReAuthed}/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<button class="modal-close is-large" aria-label="close"></button>
|
||||||
|
</div>
|
||||||
|
` : ``}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onReAuthed(event) {
|
||||||
|
if (!this.authNeeded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = event.detail.headers;
|
||||||
|
|
||||||
|
const resp = await fetch(`/wabac/api/${this.authNeeded.coll}/updateAuth`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({headers})
|
||||||
|
});
|
||||||
|
|
||||||
|
this.authNeeded = false;
|
||||||
|
|
||||||
|
this.onRefresh(null, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
@@ -1556,7 +1576,7 @@ class WrGdrive extends LitElement
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.manual = false;
|
this.manual = false;
|
||||||
this.fileId = "";
|
this.sourceId = "";
|
||||||
this.scriptLoaded = false;
|
this.scriptLoaded = false;
|
||||||
this.error = false;
|
this.error = false;
|
||||||
}
|
}
|
||||||
@@ -1564,14 +1584,14 @@ class WrGdrive extends LitElement
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
manual: { type: Boolean },
|
manual: { type: Boolean },
|
||||||
fileId: { type: String },
|
sourceId: { type: String },
|
||||||
error: { type: Boolean },
|
error: { type: Boolean },
|
||||||
reauth: { type: Boolean }
|
reauth: { type: Boolean }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updated(changedProperties) {
|
updated(changedProperties) {
|
||||||
if (changedProperties.has("fileId")) {
|
if (changedProperties.has("sourceId")) {
|
||||||
this.error = false;
|
this.error = false;
|
||||||
//this.scriptLoaded = false;
|
//this.scriptLoaded = false;
|
||||||
this.manual = false;
|
this.manual = false;
|
||||||
@@ -1598,7 +1618,8 @@ class WrGdrive extends LitElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
async authed(response) {
|
async authed(response) {
|
||||||
const fileId = this.fileId;
|
const sourceId = this.sourceId;
|
||||||
|
const fileId = sourceId.slice("googledrive://".length);
|
||||||
const metadataUrl = `https://www.googleapis.com/drive/v3/files/${fileId}`;
|
const metadataUrl = `https://www.googleapis.com/drive/v3/files/${fileId}`;
|
||||||
const authToken = response.access_token;
|
const authToken = response.access_token;
|
||||||
const headers = {"Authorization": `Bearer ${authToken}`};
|
const headers = {"Authorization": `Bearer ${authToken}`};
|
||||||
@@ -1614,8 +1635,6 @@ class WrGdrive extends LitElement
|
|||||||
this.error = false;
|
this.error = false;
|
||||||
|
|
||||||
const metadata = await resp.json();
|
const metadata = await resp.json();
|
||||||
|
|
||||||
const sourceId = `googledrive://${fileId}`;
|
|
||||||
const name = metadata.name;
|
const name = metadata.name;
|
||||||
const displayName = `Google Drive file: ` + metadata.name;
|
const displayName = `Google Drive file: ` + metadata.name;
|
||||||
|
|
||||||
@@ -1636,7 +1655,7 @@ class WrGdrive extends LitElement
|
|||||||
` : html`
|
` : html`
|
||||||
${this.error ? html`
|
${this.error ? html`
|
||||||
<div class="error has-text-danger">
|
<div class="error has-text-danger">
|
||||||
<p>${this.reauth ? 'Please reauthorize Google Drive to continue loading.' :
|
<p>${this.reauth ? 'Some resources are loaded on demand from Google Drive, which requires reauthorization.' :
|
||||||
'Could not access this file with the current Google Drive account.'}</p>
|
'Could not access this file with the current Google Drive account.'}</p>
|
||||||
<p>If you have multiple Google Drive accounts, be sure to select the correct one.</p>
|
<p>If you have multiple Google Drive accounts, be sure to select the correct one.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user