diff --git a/demo/index.js b/demo/index.js index 324a342..a0190f1 100644 --- a/demo/index.js +++ b/demo/index.js @@ -6,6 +6,18 @@ import 'bootstrap/dist/css/bootstrap.css' import App from './components/App' +import * as SolidAuthClient from '../src' + +// for demo/debug purposes +window.SolidAuthClient = SolidAuthClient +console.log('Welcome to the solid-auth-client demo!') +console.log( + 'Check out window.SolidAuthClient to explore the interface at the code level.' +) +console.log( + 'If you find a bug please file it at https://github.com/solid/solid-auth-client/issues/' +) + const container = document.createElement('div') container.id = 'container' container.className = 'container' diff --git a/package.json b/package.json index fd5dbda..51d3fa4 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "webpack-dev-server": "^2.6.1" }, "jest": { - "testURL": "https://app.biz/page?foo=bar#more-params", + "testURL": "https://app.biz/page?foo=bar#the-hash-fragment", "collectCoverage": true, "coveragePathIgnorePatterns": [ "demo", diff --git a/src/api.spec.js b/src/api.spec.js index e2894c8..100f941 100644 --- a/src/api.spec.js +++ b/src/api.spec.js @@ -1,5 +1,4 @@ /* eslint-env jest */ -/* global expect */ import fs from 'fs' import jwt from 'jsonwebtoken' import nock from 'nock' @@ -298,7 +297,7 @@ describe('currentSession', () => { expect(session.idToken).toBe(expectedIdToken) verifySerializedKey(session.sessionKey) expect(await getStoredSession()).toEqual(session) - expect(window.location.hash).toBe('') + expect(window.location.hash).toBe('#the-hash-fragment') }) }) }) @@ -376,7 +375,7 @@ describe('logout', () => { expect(session.accessToken).toBe(expectedAccessToken) expect(session.idToken).toBe(expectedIdToken) verifySerializedKey(session.sessionKey) - expect(window.location.hash).toBe('') + expect(window.location.hash).toBe('#the-hash-fragment') const storedSession = await getStoredSession() expect(storedSession).toEqual(session) await logout() diff --git a/src/storage.spec.js b/src/storage.spec.js index 898e009..6f0434e 100644 --- a/src/storage.spec.js +++ b/src/storage.spec.js @@ -1,4 +1,3 @@ -/* global expect */ /* eslint-env jest */ import { polyfillWindow, polyunfillWindow } from './spec-helpers' diff --git a/src/url-util.js b/src/url-util.js index 81ca75b..43d6e50 100644 --- a/src/url-util.js +++ b/src/url-util.js @@ -6,13 +6,6 @@ export const currentUrl = (): ?string => window.location.href export const currentUrlNoParams = (): ?string => window.location.origin + window.location.pathname -export const clearHashFragment = () => - window.history.replaceState( - '', - document.title, - window.location.pathname + window.location.search - ) - export const navigateTo = (url: string) => { window.location.href = url } diff --git a/src/url-util.spec.js b/src/url-util.spec.js index d61540c..5720a9a 100644 --- a/src/url-util.spec.js +++ b/src/url-util.spec.js @@ -1,10 +1,9 @@ -/* global expect */ /* eslint-env jest */ import { currentUrl, currentUrlNoParams } from './url-util' describe('currentUrl', () => { it('returns the current url when window.location is available', () => { - expect(currentUrl()).toBe('https://app.biz/page?foo=bar#more-params') + expect(currentUrl()).toBe('https://app.biz/page?foo=bar#the-hash-fragment') }) }) diff --git a/src/webid-oidc.js b/src/webid-oidc.js index e6dc9bd..06740d5 100644 --- a/src/webid-oidc.js +++ b/src/webid-oidc.js @@ -6,22 +6,25 @@ import RelyingParty from '@trust/oidc-rp' import PoPToken from '@trust/oidc-rp/lib/PoPToken' import type { loginOptions } from './api' -import { currentUrl, clearHashFragment, navigateTo } from './url-util' +import { currentUrl, navigateTo } from './url-util' import type { webIdOidcSession } from './session' import type { AsyncStorage } from './storage' import { defaultStorage, getData, updateStorage } from './storage' -export const login = ( +export const login = async ( idp: string, options: loginOptions -): Promise any)> => - getRegisteredRp(idp, options) - .then(rp => () => sendAuthRequest(rp, options)) - .catch(err => { - console.warn('Error logging in with WebID-OIDC') - console.error(err) - return null - }) +): Promise any)> => { + try { + const rp = await getRegisteredRp(idp, options) + await saveAppHashFragment(options.storage) + return () => sendAuthRequest(rp, options) + } catch (err) { + console.warn('Error logging in with WebID-OIDC') + console.error(err) + return null + } +} export const currentSession = async ( storage: AsyncStorage = defaultStorage() @@ -40,7 +43,7 @@ export const currentSession = async ( if (!resp) { return null } - clearHashFragment() + await restoreAppHashFragment(storage) const { idp, idToken, accessToken, clientId, sessionKey } = resp return { authType: 'WebID-OIDC', @@ -136,6 +139,19 @@ const sendAuthRequest = async ( return navigateTo(url) } +const saveAppHashFragment = (store: AsyncStorage): Promise => + updateStorage(store, data => ({ + ...data, + appHashFragment: window.location.hash + })) + +const restoreAppHashFragment = (store: AsyncStorage): Promise => + updateStorage(store, data => { + window.location.hash = data.appHashFragment + delete data.appHashFragment + return data + }) + /** * Answers whether a HTTP response requires WebID-OIDC authentication. */