2020 * @packageDocumentation
2121 */
2222import { graph , namedNode , NamedNode , Namespace , serialize , st , Statement , sym , BlankNode } from 'rdflib'
23- import solidAuthClient from 'solid-auth-client'
2423import { PaneDefinition } from 'pane-registry'
2524import { Signup } from './signup'
2625import * as widgets from '../widgets'
2726import * as ns from '../ns.js'
2827import * as utils from '../utils'
2928import { alert } from '../log'
29+ import authSession from './authSession'
3030import { AppDetails , AuthenticationContext } from './types'
3131import * as debug from '../debug'
3232import { textInputStyle , buttonStyle , commentStyle } from '../style'
@@ -35,7 +35,7 @@ import { Quad_Object } from 'rdflib/lib/tf-types'
3535import { solidLogicSingleton } from '../logic'
3636import { CrossOriginForbiddenError , FetchError , NotFoundError , SameOriginForbiddenError , UnauthorizedError , ACL_LINK } from 'solid-logic'
3737
38- export { solidAuthClient }
38+ export { authSession }
3939
4040// const userCheckSite = 'https://databox.me/'
4141
@@ -97,13 +97,8 @@ export function defaultTestUser (): NamedNode | null {
9797 * @returns Named Node or null
9898 */
9999export function currentUser ( ) : NamedNode | null {
100- const str = localStorage [ 'solid-auth-client' ]
101- if ( str ) {
102- const da = JSON . parse ( str )
103- if ( da . session && da . session . webId ) {
104- // @@ TODO check has not expired
105- return sym ( da . session . webId )
106- }
100+ if ( authSession . info . webId ) {
101+ return sym ( authSession . info . webId )
107102 }
108103 return offlineTestID ( ) // null unless testing
109104 // JSON.parse(localStorage['solid-auth-client']).session.webId
@@ -846,11 +841,10 @@ function signInOrSignUpBox (
846841 signInPopUpButton . setAttribute ( 'value' , 'Log in' )
847842 signInPopUpButton . setAttribute ( 'style' , `${ signInButtonStyle } background-color: #eef;` )
848843
849- signInPopUpButton . addEventListener ( 'click' , ( ) => {
850- const offline = offlineTestID ( )
851- if ( offline ) return setUserCallback ( offline . uri )
852- return solidAuthClient . popupLogin ( ) . then ( session => {
853- const webIdURI = session . webId
844+ authSession . onLogin ( ( ) => {
845+ const sessionInfo = authSession . info
846+ if ( sessionInfo && sessionInfo . isLoggedIn ) {
847+ const webIdURI = sessionInfo . webId
854848 // setUserCallback(webIdURI)
855849 const divs = dom . getElementsByClassName ( magicClassName )
856850 debug . log ( `Logged in, ${ divs . length } panels to be serviced` )
@@ -871,6 +865,23 @@ function signInOrSignUpBox (
871865 }
872866 }
873867 }
868+ }
869+ } )
870+
871+ signInPopUpButton . addEventListener ( 'click' , ( ) => {
872+ const offline = offlineTestID ( )
873+ if ( offline ) return setUserCallback ( offline . uri )
874+
875+ const thisUrl = new URL ( window . location . href ) . origin
876+ // HACK solid-client-authn-js no longer comes with its own UI for selecting
877+ // an IDP. This was the easiest way to get the user to select.
878+ // TODO: make a nice UI to select an IDP
879+ const issuer = prompt ( 'Enter an issuer' , thisUrl )
880+ authSession . login ( {
881+ // @ts -ignore this library requires a specific kind of URL that isn't global
882+ redirectUrl : window . location . href ,
883+ // @ts -ignore
884+ oidcIssuer : issuer
874885 } )
875886 } , false )
876887
@@ -894,8 +905,8 @@ function signInOrSignUpBox (
894905/**
895906 * @returns {Promise<string|null> } Resolves with WebID URI or null
896907 */
897- function webIdFromSession ( session ?: { webId : string } ) : string | null {
898- const webId = session ? session . webId : null
908+ function webIdFromSession ( session ?: { webId ? : string } ) : string | null {
909+ const webId = session ?. webId ? session . webId : null
899910 if ( webId ) {
900911 saveUser ( webId )
901912 }
@@ -912,42 +923,59 @@ function checkCurrentUser () {
912923}
913924*/
914925
926+ // HACK this global variable exists to prevent authSession.handleIncomingRedirect
927+ // From being called twice. It would not be needed if it automatically redirected
928+ // by iteself. See https://github.com/inrupt/solid-client-authn-js/issues/514
929+ let checkingRedirect = false
930+
915931/**
916932 * Retrieves currently logged in webId from either
917- * defaultTestUser or SolidAuthClient
933+ * defaultTestUser or SolidAuth
918934 * @param [setUserCallback] Optional callback
919935 *
920936 * @returns Resolves with webId uri, if no callback provided
921937 */
922- export function checkUser < T > (
938+ export async function checkUser < T > (
923939 setUserCallback ?: ( me : NamedNode | null ) => T
924- ) : Promise < NamedNode | T > {
940+ ) : Promise < NamedNode | T | null > {
941+ /**
942+ * Handle a successful authentication redirect
943+ */
944+ // HACK normally you wouldn't need to do a check to see if 'code' is in the
945+ // query, but it was removed from solid-client-authn-js
946+ // See https://github.com/inrupt/solid-client-authn-js/issues/421
947+ // Remove this after
948+ const authCode = new URL ( window . location . href ) . searchParams . get ( 'code' )
949+ if ( authCode && ! checkingRedirect ) {
950+ checkingRedirect = true
951+ // Being redirected after requesting a token
952+ await authSession
953+ . handleIncomingRedirect ( window . location . href )
954+ // HACK solid-client-authn-js should automatically remove code and state
955+ // from the URL, but it doesn't, so we do it manually here
956+ // see https://github.com/inrupt/solid-client-authn-js/issues/514
957+ const newPageUrl = new URL ( window . location . href )
958+ newPageUrl . searchParams . delete ( 'code' )
959+ newPageUrl . searchParams . delete ( 'state' )
960+ window . history . replaceState ( { } , '' , newPageUrl . toString ( ) )
961+ }
962+
925963 // Check to see if already logged in / have the WebID
926- const me = defaultTestUser ( )
964+ let me = defaultTestUser ( )
927965 if ( me ) {
928966 return Promise . resolve ( setUserCallback ? setUserCallback ( me ) : me )
929967 }
930968
931969 // doc = solidLogicSingleton.store.any(doc, ns.link('userMirror')) || doc
970+ const webId = webIdFromSession ( authSession . info )
932971
933- return solidAuthClient
934- . currentSession ( )
935- . then ( webIdFromSession )
936- . catch ( err => {
937- debug . log ( 'Error fetching currentSession:' , err )
938- } )
939- . then ( webId => {
940- // if (webId.startsWith('dns:')) { // legacy rww.io pseudo-users
941- // webId = null
942- // }
943- const me = saveUser ( webId )
972+ me = saveUser ( webId )
944973
945- if ( me ) {
946- debug . log ( `(Logged in as ${ me } by authentication)` )
947- }
974+ if ( me ) {
975+ debug . log ( `(Logged in as ${ me } by authentication)` )
976+ }
948977
949- return setUserCallback ? setUserCallback ( me ) : me
950- } )
978+ return Promise . resolve ( setUserCallback ? setUserCallback ( me ) : me )
951979}
952980
953981/**
@@ -986,7 +1014,7 @@ export function loginStatusBox (
9861014
9871015 function logoutButtonHandler ( _event ) {
9881016 // UI.preferences.set('me', '')
989- solidAuthClient . logout ( ) . then (
1017+ authSession . logout ( ) . then (
9901018 function ( ) {
9911019 const message = `Your WebID was ${ me } . It has been forgotten.`
9921020 me = null
@@ -1025,39 +1053,35 @@ export function loginStatusBox (
10251053 }
10261054
10271055 box . refresh = function ( ) {
1028- solidAuthClient . currentSession ( ) . then (
1029- session => {
1030- if ( session && session . webId ) { // offline
1031- me = sym ( session . webId )
1032- } else {
1033- me = offlineTestID ( ) // null unless testing
1034- }
1035- if ( ( me && box . me !== me . uri ) || ( ! me && box . me ) ) {
1036- widgets . clearElement ( box )
1037- if ( me ) {
1038- box . appendChild ( logoutButton ( me , options ) )
1039- } else {
1040- box . appendChild ( signInOrSignUpBox ( dom , setIt , options ) )
1041- }
1042- }
1043- box . me = me ? me . uri : null
1044- } ,
1045- err => {
1046- alert ( `loginStatusBox: ${ err } ` )
1056+ const sessionInfo = authSession . info
1057+ if ( sessionInfo && sessionInfo . webId ) {
1058+ me = sym ( sessionInfo . webId )
1059+ } else {
1060+ me = null
1061+ }
1062+ if ( ( me && box . me !== me . uri ) || ( ! me && box . me ) ) {
1063+ widgets . clearElement ( box )
1064+ if ( me ) {
1065+ box . appendChild ( logoutButton ( me , options ) )
1066+ } else {
1067+ box . appendChild ( signInOrSignUpBox ( dom , setIt , options ) )
10471068 }
1048- )
1069+ }
1070+ box . me = me ? me . uri : null
10491071 }
10501072
1051- if ( solidAuthClient . trackSession ) {
1052- solidAuthClient . trackSession ( session => {
1053- if ( session && session . webId ) {
1054- me = sym ( session . webId )
1055- } else {
1056- me = null
1057- }
1058- box . refresh ( )
1059- } )
1073+ function trackSession ( ) {
1074+ const sessionInfo = authSession . info
1075+ if ( sessionInfo && sessionInfo . webId ) {
1076+ me = sym ( sessionInfo . webId )
1077+ } else {
1078+ me = null
1079+ }
1080+ box . refresh ( )
10601081 }
1082+ trackSession ( )
1083+ authSession . onLogin ( trackSession )
1084+ authSession . onLogout ( trackSession )
10611085
10621086 box . me = '99999' // Force refresh
10631087 box . refresh ( )
0 commit comments