@aerogel/plugin-solid 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/InruptAuthenticator.lazy-BvpQLGoj.js +9 -0
- package/dist/InruptAuthenticator.lazy-BvpQLGoj.js.map +1 -0
- package/dist/LegacyAuthenticator.lazy-ChFFqP14.js +5 -0
- package/dist/LegacyAuthenticator.lazy-ChFFqP14.js.map +1 -0
- package/dist/aerogel-plugin-solid.d.ts +120 -92
- package/dist/aerogel-plugin-solid.js +724 -0
- package/dist/aerogel-plugin-solid.js.map +1 -0
- package/package.json +35 -28
- package/src/auth/Authenticator.ts +10 -8
- package/src/auth/authenticators/InruptAuthenticator.lazy.ts +1 -0
- package/src/auth/authenticators/InruptAuthenticator.ts +41 -12
- package/src/auth/authenticators/LegacyAuthenticator.lazy.ts +1 -0
- package/src/auth/authenticators/LegacyAuthenticator.ts +80 -0
- package/src/auth/index.ts +3 -1
- package/src/components/SolidAvatar.vue +35 -0
- package/src/components/SolidImage.vue +33 -0
- package/src/components/SolidLogin.vue +141 -0
- package/src/components/index.ts +3 -4
- package/src/errors/AuthenticationFailedError.ts +22 -0
- package/src/errors/index.ts +3 -4
- package/src/forms/validation.ts +11 -0
- package/src/index.css +1 -0
- package/src/index.test.ts +24 -0
- package/src/index.ts +65 -0
- package/src/services/Solid.state.ts +12 -16
- package/src/services/Solid.ts +317 -139
- package/src/testing/setup.ts +11 -0
- package/src/types/env.d.ts +1 -0
- package/src/types/solid-auth-client.d.ts +21 -0
- package/.eslintrc.js +0 -7
- package/dist/aerogel-plugin-solid.cjs.js +0 -2
- package/dist/aerogel-plugin-solid.cjs.js.map +0 -1
- package/dist/aerogel-plugin-solid.esm.js +0 -2
- package/dist/aerogel-plugin-solid.esm.js.map +0 -1
- package/noeldemartin.config.js +0 -2
- package/src/components/AGSolidStatus.ts +0 -5
- package/src/components/AGSolidStatus.vue +0 -60
- package/src/main.ts +0 -43
- package/tsconfig.json +0 -10
package/.eslintrc.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@aerogel/core"),t=require("soukai-solid"),r=require("@babel/runtime/helpers/defineProperty");require("core-js/modules/esnext.async-iterator.find.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js");var i=require("@noeldemartin/utils"),s=require("@noeldemartin/solid-utils");require("core-js/modules/esnext.async-iterator.for-each.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.async-iterator.map.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.async-iterator.constructor.js"),require("core-js/modules/esnext.async-iterator.to-array.js"),require("core-js/modules/esnext.iterator.to-array.js");var n=require("vue");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function a(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var l=o(r);class AuthenticationCancelledError extends i.JSError{}class u extends i.JSError{constructor(e,t){super(`Container at ${e.url} is already in use`,t)}}class c{constructor(){l.default(this,"name",void 0),l.default(this,"authenticatedFetch",void 0),l.default(this,"booted",void 0),l.default(this,"listeners",i.arr([])),l.default(this,"_engine",void 0)}get engine(){return this._engine=this._engine??new t.SolidEngine(this.requireAuthenticatedFetch()),this._engine}getAuthenticatedFetch(){return this.authenticatedFetch??null}requireAuthenticatedFetch(){return this.authenticatedFetch??i.fail("Authenticated fetch is not ready")}addListener(e){return this.listeners.includes(e)||this.listeners.push(e),()=>{this.removeListener(e)}}removeListener(e){this.listeners.includes(e)&&this.listeners.remove(e)}async boot(){if(this.booted)return this.booted;this.booted=new i.PromisedValue,await this.restoreSession(),this.booted.resolve()}async initAuthenticatedFetch(e){this.authenticatedFetch=e,await this.notifyListeners("onAuthenticatedFetchReady",e)}async startSession(e){const t={authenticator:this,...e};return await this.notifyListeners("onSessionStarted",t),t}async failSession(e,t){await this.notifyListeners("onSessionFailed",e,t)}async endSession(){await this.notifyListeners("onSessionEnded")}async notifyListeners(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),i=1;i<t;i++)r[i-1]=arguments[i];await Promise.all(this.listeners.toArray().map((async t=>{const i=t[e];await(i?.(...r))})))}}const d="inrupt-authenticator";const h={},g={inrupt:new class extends c{constructor(){super(...arguments),l.default(this,"_fetch",void 0),l.default(this,"_login",void 0),l.default(this,"_logout",void 0),l.default(this,"_handleIncomingRedirect",void 0)}async login(e){return i.Storage.set(d,!0),await this._login({oidcIssuer:e}),await i.after({seconds:60}),i.fail("Browser should have redirected, but it didn't")}async logout(){await this._logout(),await this.endSession()}async restoreSession(){const{fetch:e,handleIncomingRedirect:t,login:r,logout:i}=await Promise.resolve().then((function(){return a(require("@inrupt/solid-client-authn-browser"))}));this._fetch=e,this._login=r,this._logout=i,this._handleIncomingRedirect=t,await this.loginFromRedirect()}async loginFromRedirect(){if(!i.Storage.has(d))return;const e=await this._handleIncomingRedirect(window.location.href);i.Storage.remove(d),e?.isLoggedIn&&e.webId&&await this.initSession(e.webId)}async initSession(e){await this.initAuthenticatedFetch(this._fetch);try{const{default:t}=await Promise.resolve().then((function(){return x})),r=await t.requireUserProfile(e);await this.startSession({user:r,loginUrl:e})}catch(t){await this.failSession(e,t)}}}};function f(e){h.default=e}function p(e){return h[e]}function y(e){Object.entries(e).forEach((e=>{let[t,r]=e;return w(t,r)}))}function w(e,t){h[e]=t,t.name=t.name??e}var S=e.defineServiceState({name:"solid",persist:["autoReconnect","dismissed","previousSession","profiles","staleProfiles"],initialState:{autoReconnect:!1,dismissed:!1,ignorePreviousSessionError:!1,loginError:null,loginOngoing:!1,preferredAuthenticator:null,previousSession:null,profiles:{},session:null,loginStale:!1,staleProfiles:[]},serialize:e=>(e.previousSession?.error instanceof Error&&(e.previousSession.error=e.previousSession.error.message),e),computed:{loggedIn:e=>!!e.session,user:e=>e.session?.user??null,userAvatarUrl:e=>e.session?.user?.avatarUrl??e.previousSession?.avatarUrl??null,wasLoggedIn:e=>!!e.previousSession?.loginUrl,authenticator:e=>e.session?.authenticator??null,hasLoggedIn(){return this.loggedIn||this.wasLoggedIn},fetch(){return this.authenticator?.getAuthenticatedFetch()??window.fetch.bind(window)},error:e=>e.loginError?e.loginError??null:e.ignorePreviousSessionError?null:e.previousSession?.error??null}});class m extends S{constructor(){super(...arguments),l.default(this,"publicTypeIndexes",{}),l.default(this,"privateTypeIndexes",{})}isLoggedIn(){return this.loggedIn}requireAuthenticator(){return this.authenticator??i.fail("Could not get authenticator")}requireUser(){return this.user??i.fail("Could not get user profile")}requireUserProfile(e){return this.getUserProfile(e,!0)}async getUserProfile(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.profiles[e]??i.tap(await s.fetchLoginUserProfile(e,{fetch:this.fetch,required:t}),(e=>e&&this.rememberProfile(e)))}async refreshUserProfile(){if(!this.isLoggedIn())return;this.setState({profiles:i.objectWithout(this.profiles,[this.user.webId])});const e=await this.requireUserProfile(this.user.webId);this.setState({session:{...this.session,user:e}})}async login(t,r){if(r=r??this.preferredAuthenticator??"default",e.App.isDevelopment&&"devserver"===t&&(t="http://localhost:4000"),this.loggedIn)return!0;if(this.loginOngoing)throw new Error("Authentication already in progress");const s=setTimeout((()=>this.loginStale=!0),1e4);this.loginOngoing=!0;try{const s=await this.getUserProfile(t),n=s?.oidcIssuerUrl??i.urlRoot(s?.webId??t),o=await this.bootAuthenticator(r);return this.setState({dismissed:!1,ignorePreviousSessionError:!0,previousSession:{loginUrl:t,avatarUrl:s?.avatarUrl,authenticator:r,error:e.translateWithDefault("auth.stuckConnecting","We didn't hear back from the identity provider, maybe try reconnecting?")}}),await o.login(n),!0}catch(t){return t instanceof AuthenticationCancelledError||(e.App.isMounted?e.Errors.report(t):this.setState({loginError:t})),!1}finally{clearTimeout(s),this.loginOngoing=!1,this.loginStale=!1}}async reconnect(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.loggedIn||!this.previousSession||null!==this.previousSession.error&&!e||await this.login(this.previousSession.loginUrl,this.previousSession.authenticator)}async logout(){(arguments.length>0&&void 0!==arguments[0]&&arguments[0]||await e.UI.confirm(e.translateWithDefault("solid.logoutConfirm","Are you sure you want to log out?")))&&this.previousSession&&(this.setState({previousSession:null}),this.isLoggedIn()&&await this.authenticator.logout(),await e.Events.emit("logout"))}dismiss(){this.setState({dismissed:!0})}async findOrCreatePrivateTypeIndex(){if(!this.isLoggedIn())throw new Error("Can't find or create a type index because the user is not logged in");const e=this.user.webId;return this.privateTypeIndexes[e]=this.privateTypeIndexes[e]??i.PromisedValue.from((async()=>await this.findPrivateTypeIndex()??await this.createPrivateTypeIndex())())}async findOrCreatePublicTypeIndex(){if(!this.isLoggedIn())throw new Error("Can't find or create a type index because the user is not logged in");const e=this.user.webId;return this.publicTypeIndexes[e]=this.publicTypeIndexes[e]??i.PromisedValue.from((async()=>await this.findPublicTypeIndex()??await this.createPublicTypeIndex())())}async createPrivateContainer(e){const r=this.requireAuthenticator().engine;return t.SolidContainer.withEngine(r,(async()=>{const r=await t.SolidContainer.find(e.url);if(r&&!e.reuseExisting)throw new u(r);const i=r??new t.SolidContainer({url:e.url,name:e.url});return await i.save(),e.register&&await i.register(e.register.typeIndex.url,e.register.modelClass),i}))}async boot(){await super.boot(),await e.Errors.booted,i.hasLocationQueryParameter("authenticator")&&this.setState({preferredAuthenticator:i.getLocationQueryParameter("authenticator")}),i.hasLocationQueryParameter("refreshProfile")&&this.setState({staleProfiles:i.arrayUnique(this.staleProfiles.concat(i.arrayFilter([this.session?.user.webId,this.previousSession?.loginUrl])))}),await this.restorePreviousSession(),await this.startupReconnect()}async findPrivateTypeIndex(){const e=this.requireUser(),r=this.requireAuthenticator();return t.SolidTypeIndex.withEngine(r.engine,(()=>t.SolidTypeIndex.find(e.privateTypeIndexUrl)))}async createPrivateTypeIndex(){const e=this.requireUser(),r=this.requireAuthenticator(),s=await t.SolidTypeIndex.withEngine(r.engine).createPrivate(e);return i.tap(s,(()=>{e.privateTypeIndexUrl=s.url,this.rememberProfile(e)}))}async findPublicTypeIndex(){return this.user?.publicTypeIndexUrl?t.SolidTypeIndex.find(this.user.publicTypeIndexUrl):null}async createPublicTypeIndex(){if(!this.isLoggedIn())throw new Error("Can't create a type index because the user is not logged in");const e=this.user,r=await t.SolidTypeIndex.withEngine(this.authenticator.engine,(()=>t.SolidTypeIndex.createPublic(e)));return i.tap(r,(()=>{e.publicTypeIndexUrl=r.url,this.rememberProfile(e)}))}async restorePreviousSession(){this.previousSession&&await this.bootAuthenticator(this.previousSession.authenticator)}async startupReconnect(){this.reconnectOnStartup()&&await this.reconnect()}reconnectOnStartup(){return i.hasLocationQueryParameter("autoReconnect")?i.parseBoolean(i.getLocationQueryParameter("autoReconnect")):this.autoReconnect}async bootAuthenticator(r){const i=p(r);return i.addListener({onSessionStarted:async r=>{this.setState({session:r,previousSession:{authenticator:i.name,loginUrl:r.loginUrl,avatarUrl:r.user.avatarUrl,error:null}}),(r.user.cloaked||!r.user.writableProfileUrl||this.staleProfiles.includes(r.user.webId))&&await this.refreshUserProfile(),t.SolidACLAuthorization.setEngine(r.authenticator.engine),await e.Events.emit("login",r)},onSessionFailed:async(e,t)=>{this.setState({session:null,previousSession:{authenticator:i.name,loginUrl:e,error:t}})},onSessionEnded:()=>this.setState({session:null}),onAuthenticatedFetchReady:t=>e.Events.emit("authenticated-fetch-ready",t)}),await i.boot(),i}rememberProfile(e){this.setState({profiles:{...this.profiles,[e.webId]:e},staleProfiles:i.arrayWithout(this.staleProfiles,e.webId)})}}var v=i.facade(new m),x=Object.freeze({__proto__:null,SolidService:m,default:v});const b={class:"flex flex-col gap-3"},I={class:"flex flex-col"};var P=n.defineComponent({__name:"AGSolidStatus",setup(t){const r=e.useForm({url:e.requiredStringInput()});return(t,i)=>(n.openBlock(),n.createElementBlock("div",null,[t.$solid.loginStale?n.renderSlot(t.$slots,"login-stale",{key:0},(()=>[n.createVNode(n.unref(e.AGMarkdown),{text:t.$td("solid.loginStale","This is taking too long...")},null,8,["text"])])):n.createCommentVNode("v-if",!0),t.$solid.loginOngoing?n.renderSlot(t.$slots,"login-ongoing",{key:1},(()=>[n.createVNode(n.unref(e.AGMarkdown),{text:t.$td("ui.loading","Loading...")},null,8,["text"])])):t.$solid.isLoggedIn()?n.renderSlot(t.$slots,"logged-in",{key:2,session:t.$solid.session},(()=>[n.createElementVNode("div",b,[n.createVNode(n.unref(e.AGMarkdown),{text:t.$td("solid.loggedIn",{userName:t.$solid.user.name??t.$solid.user.webId,userWebId:t.$solid.user.webId},"You are logged in as [{userName}]({userWebId})")},null,8,["text"]),n.createVNode(n.unref(e.AGButton),{onClick:i[0]||(i[0]=e=>t.$solid.logout())},{default:n.withCtx((()=>[n.createTextVNode(n.toDisplayString(t.$td("solid.logout","Logout")),1)])),_:1})])])):n.renderSlot(t.$slots,"logged-out",{key:3},(()=>[n.createElementVNode("div",I,[n.createVNode(n.unref(e.AGForm),{form:n.unref(r),class:"flex",onSubmit:i[1]||(i[1]=e=>t.$solid.login(n.unref(r).url))},{default:n.withCtx((()=>[n.createVNode(n.unref(e.AGInput),{name:"url","aria-label":t.$td("solid.url","Login url"),placeholder:t.$td("solid.placeholder","https://...")},null,8,["aria-label","placeholder"]),n.createVNode(n.unref(e.AGButton),{submit:""},{default:n.withCtx((()=>[n.createTextVNode(n.toDisplayString(t.$td("solid.login","Login")),1)])),_:1})])),_:1},8,["form"]),t.$solid.wasLoggedIn?(n.openBlock(),n.createBlock(n.unref(e.AGButton),{key:0,class:"mt-3",onClick:i[2]||(i[2]=e=>t.$solid.reconnect(!0))},{default:n.withCtx((()=>[n.createTextVNode(n.toDisplayString(t.$td("solid.reconnect","Reconnect")),1)])),_:1})):n.createCommentVNode("v-if",!0),t.$solid.previousSession?.error?(n.openBlock(),n.createBlock(n.unref(e.AGMarkdown),{key:1,class:"mt-1 self-center text-sm text-red-800",text:t.$td("solid.previousLoginError","Previous login attempt failed")},null,8,["text"])):n.createCommentVNode("v-if",!0)])]))]))}});P.__file="src/components/AGSolidStatus.vue";const A={$solid:v};exports.AGSolidStatus=P,exports.AuthenticationCancelledError=AuthenticationCancelledError,exports.ContainerAlreadyInUse=u,exports.Solid=v,exports.authenticators=g,exports.default=function(){let r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{async install(i){t.bootSolidModels(),y({...g,...r.authenticators??{}}),f(p(r.defaultAuthenticator??"inrupt")),await e.bootServices(i,A)}}},exports.getAuthenticator=p,exports.registerAuthenticator=w,exports.registerAuthenticators=y,exports.setDefaultAuthenticator=f;
|
|
2
|
-
//# sourceMappingURL=aerogel-plugin-solid.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aerogel-plugin-solid.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{defineServiceState as e,App as t,translateWithDefault as i,Errors as s,UI as r,Events as n,useForm as o,requiredStringInput as a,AGMarkdown as l,AGButton as u,AGForm as c,AGInput as d,bootServices as h}from"@aerogel/core";import{SolidEngine as g,SolidContainer as f,SolidTypeIndex as p,SolidACLAuthorization as m,bootSolidModels as w}from"soukai-solid";import y from"@babel/runtime/helpers/esm/defineProperty";import"core-js/modules/esnext.async-iterator.find.js";import"core-js/modules/esnext.iterator.constructor.js";import"core-js/modules/esnext.iterator.find.js";import{JSError as v,arr as S,fail as b,PromisedValue as I,Storage as x,after as P,facade as U,tap as A,objectWithout as _,urlRoot as $,hasLocationQueryParameter as L,getLocationQueryParameter as E,arrayUnique as T,arrayFilter as j,parseBoolean as C,arrayWithout as F}from"@noeldemartin/utils";import{fetchLoginUserProfile as R}from"@noeldemartin/solid-utils";import"core-js/modules/esnext.async-iterator.for-each.js";import"core-js/modules/esnext.iterator.for-each.js";import"core-js/modules/esnext.async-iterator.map.js";import"core-js/modules/esnext.iterator.map.js";import"core-js/modules/esnext.async-iterator.constructor.js";import"core-js/modules/esnext.async-iterator.to-array.js";import"core-js/modules/esnext.iterator.to-array.js";import{defineComponent as k,openBlock as q,createElementBlock as O,renderSlot as G,createVNode as W,unref as z,createCommentVNode as N,createElementVNode as B,withCtx as D,createTextVNode as M,toDisplayString as Y,createBlock as H}from"vue";class AuthenticationCancelledError extends v{}class J extends v{constructor(e,t){super(`Container at ${e.url} is already in use`,t)}}class K{constructor(){y(this,"name",void 0),y(this,"authenticatedFetch",void 0),y(this,"booted",void 0),y(this,"listeners",S([])),y(this,"_engine",void 0)}get engine(){return this._engine=this._engine??new g(this.requireAuthenticatedFetch()),this._engine}getAuthenticatedFetch(){return this.authenticatedFetch??null}requireAuthenticatedFetch(){return this.authenticatedFetch??b("Authenticated fetch is not ready")}addListener(e){return this.listeners.includes(e)||this.listeners.push(e),()=>{this.removeListener(e)}}removeListener(e){this.listeners.includes(e)&&this.listeners.remove(e)}async boot(){if(this.booted)return this.booted;this.booted=new I,await this.restoreSession(),this.booted.resolve()}async initAuthenticatedFetch(e){this.authenticatedFetch=e,await this.notifyListeners("onAuthenticatedFetchReady",e)}async startSession(e){const t={authenticator:this,...e};return await this.notifyListeners("onSessionStarted",t),t}async failSession(e,t){await this.notifyListeners("onSessionFailed",e,t)}async endSession(){await this.notifyListeners("onSessionEnded")}async notifyListeners(e){for(var t=arguments.length,i=new Array(t>1?t-1:0),s=1;s<t;s++)i[s-1]=arguments[s];await Promise.all(this.listeners.toArray().map((async t=>{const s=t[e];await(s?.(...i))})))}}const Q="inrupt-authenticator";const V={},X={inrupt:new class extends K{constructor(){super(...arguments),y(this,"_fetch",void 0),y(this,"_login",void 0),y(this,"_logout",void 0),y(this,"_handleIncomingRedirect",void 0)}async login(e){return x.set(Q,!0),await this._login({oidcIssuer:e}),await P({seconds:60}),b("Browser should have redirected, but it didn't")}async logout(){await this._logout(),await this.endSession()}async restoreSession(){const{fetch:e,handleIncomingRedirect:t,login:i,logout:s}=await import("@inrupt/solid-client-authn-browser");this._fetch=e,this._login=i,this._logout=s,this._handleIncomingRedirect=t,await this.loginFromRedirect()}async loginFromRedirect(){if(!x.has(Q))return;const e=await this._handleIncomingRedirect(window.location.href);x.remove(Q),e?.isLoggedIn&&e.webId&&await this.initSession(e.webId)}async initSession(e){await this.initAuthenticatedFetch(this._fetch);try{const{default:t}=await Promise.resolve().then((function(){return oe})),i=await t.requireUserProfile(e);await this.startSession({user:i,loginUrl:e})}catch(t){await this.failSession(e,t)}}}};function Z(e){V.default=e}function ee(e){return V[e]}function te(e){Object.entries(e).forEach((e=>{let[t,i]=e;return ie(t,i)}))}function ie(e,t){V[e]=t,t.name=t.name??e}var se=e({name:"solid",persist:["autoReconnect","dismissed","previousSession","profiles","staleProfiles"],initialState:{autoReconnect:!1,dismissed:!1,ignorePreviousSessionError:!1,loginError:null,loginOngoing:!1,preferredAuthenticator:null,previousSession:null,profiles:{},session:null,loginStale:!1,staleProfiles:[]},serialize:e=>(e.previousSession?.error instanceof Error&&(e.previousSession.error=e.previousSession.error.message),e),computed:{loggedIn:e=>!!e.session,user:e=>e.session?.user??null,userAvatarUrl:e=>e.session?.user?.avatarUrl??e.previousSession?.avatarUrl??null,wasLoggedIn:e=>!!e.previousSession?.loginUrl,authenticator:e=>e.session?.authenticator??null,hasLoggedIn(){return this.loggedIn||this.wasLoggedIn},fetch(){return this.authenticator?.getAuthenticatedFetch()??window.fetch.bind(window)},error:e=>e.loginError?e.loginError??null:e.ignorePreviousSessionError?null:e.previousSession?.error??null}});class re extends se{constructor(){super(...arguments),y(this,"publicTypeIndexes",{}),y(this,"privateTypeIndexes",{})}isLoggedIn(){return this.loggedIn}requireAuthenticator(){return this.authenticator??b("Could not get authenticator")}requireUser(){return this.user??b("Could not get user profile")}requireUserProfile(e){return this.getUserProfile(e,!0)}async getUserProfile(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.profiles[e]??A(await R(e,{fetch:this.fetch,required:t}),(e=>e&&this.rememberProfile(e)))}async refreshUserProfile(){if(!this.isLoggedIn())return;this.setState({profiles:_(this.profiles,[this.user.webId])});const e=await this.requireUserProfile(this.user.webId);this.setState({session:{...this.session,user:e}})}async login(e,r){if(r=r??this.preferredAuthenticator??"default",t.isDevelopment&&"devserver"===e&&(e="http://localhost:4000"),this.loggedIn)return!0;if(this.loginOngoing)throw new Error("Authentication already in progress");const n=setTimeout((()=>this.loginStale=!0),1e4);this.loginOngoing=!0;try{const t=await this.getUserProfile(e),s=t?.oidcIssuerUrl??$(t?.webId??e),n=await this.bootAuthenticator(r);return this.setState({dismissed:!1,ignorePreviousSessionError:!0,previousSession:{loginUrl:e,avatarUrl:t?.avatarUrl,authenticator:r,error:i("auth.stuckConnecting","We didn't hear back from the identity provider, maybe try reconnecting?")}}),await n.login(s),!0}catch(e){return e instanceof AuthenticationCancelledError||(t.isMounted?s.report(e):this.setState({loginError:e})),!1}finally{clearTimeout(n),this.loginOngoing=!1,this.loginStale=!1}}async reconnect(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.loggedIn||!this.previousSession||null!==this.previousSession.error&&!e||await this.login(this.previousSession.loginUrl,this.previousSession.authenticator)}async logout(){(arguments.length>0&&void 0!==arguments[0]&&arguments[0]||await r.confirm(i("solid.logoutConfirm","Are you sure you want to log out?")))&&this.previousSession&&(this.setState({previousSession:null}),this.isLoggedIn()&&await this.authenticator.logout(),await n.emit("logout"))}dismiss(){this.setState({dismissed:!0})}async findOrCreatePrivateTypeIndex(){if(!this.isLoggedIn())throw new Error("Can't find or create a type index because the user is not logged in");const e=this.user.webId;return this.privateTypeIndexes[e]=this.privateTypeIndexes[e]??I.from((async()=>await this.findPrivateTypeIndex()??await this.createPrivateTypeIndex())())}async findOrCreatePublicTypeIndex(){if(!this.isLoggedIn())throw new Error("Can't find or create a type index because the user is not logged in");const e=this.user.webId;return this.publicTypeIndexes[e]=this.publicTypeIndexes[e]??I.from((async()=>await this.findPublicTypeIndex()??await this.createPublicTypeIndex())())}async createPrivateContainer(e){const t=this.requireAuthenticator().engine;return f.withEngine(t,(async()=>{const t=await f.find(e.url);if(t&&!e.reuseExisting)throw new J(t);const i=t??new f({url:e.url,name:e.url});return await i.save(),e.register&&await i.register(e.register.typeIndex.url,e.register.modelClass),i}))}async boot(){await super.boot(),await s.booted,L("authenticator")&&this.setState({preferredAuthenticator:E("authenticator")}),L("refreshProfile")&&this.setState({staleProfiles:T(this.staleProfiles.concat(j([this.session?.user.webId,this.previousSession?.loginUrl])))}),await this.restorePreviousSession(),await this.startupReconnect()}async findPrivateTypeIndex(){const e=this.requireUser(),t=this.requireAuthenticator();return p.withEngine(t.engine,(()=>p.find(e.privateTypeIndexUrl)))}async createPrivateTypeIndex(){const e=this.requireUser(),t=this.requireAuthenticator(),i=await p.withEngine(t.engine).createPrivate(e);return A(i,(()=>{e.privateTypeIndexUrl=i.url,this.rememberProfile(e)}))}async findPublicTypeIndex(){return this.user?.publicTypeIndexUrl?p.find(this.user.publicTypeIndexUrl):null}async createPublicTypeIndex(){if(!this.isLoggedIn())throw new Error("Can't create a type index because the user is not logged in");const e=this.user,t=await p.withEngine(this.authenticator.engine,(()=>p.createPublic(e)));return A(t,(()=>{e.publicTypeIndexUrl=t.url,this.rememberProfile(e)}))}async restorePreviousSession(){this.previousSession&&await this.bootAuthenticator(this.previousSession.authenticator)}async startupReconnect(){this.reconnectOnStartup()&&await this.reconnect()}reconnectOnStartup(){return L("autoReconnect")?C(E("autoReconnect")):this.autoReconnect}async bootAuthenticator(e){const t=ee(e);return t.addListener({onSessionStarted:async e=>{this.setState({session:e,previousSession:{authenticator:t.name,loginUrl:e.loginUrl,avatarUrl:e.user.avatarUrl,error:null}}),(e.user.cloaked||!e.user.writableProfileUrl||this.staleProfiles.includes(e.user.webId))&&await this.refreshUserProfile(),m.setEngine(e.authenticator.engine),await n.emit("login",e)},onSessionFailed:async(e,i)=>{this.setState({session:null,previousSession:{authenticator:t.name,loginUrl:e,error:i}})},onSessionEnded:()=>this.setState({session:null}),onAuthenticatedFetchReady:e=>n.emit("authenticated-fetch-ready",e)}),await t.boot(),t}rememberProfile(e){this.setState({profiles:{...this.profiles,[e.webId]:e},staleProfiles:F(this.staleProfiles,e.webId)})}}var ne=U(new re),oe=Object.freeze({__proto__:null,SolidService:re,default:ne});const ae={class:"flex flex-col gap-3"},le={class:"flex flex-col"};var ue=k({__name:"AGSolidStatus",setup(e){const t=o({url:a()});return(e,i)=>(q(),O("div",null,[e.$solid.loginStale?G(e.$slots,"login-stale",{key:0},(()=>[W(z(l),{text:e.$td("solid.loginStale","This is taking too long...")},null,8,["text"])])):N("v-if",!0),e.$solid.loginOngoing?G(e.$slots,"login-ongoing",{key:1},(()=>[W(z(l),{text:e.$td("ui.loading","Loading...")},null,8,["text"])])):e.$solid.isLoggedIn()?G(e.$slots,"logged-in",{key:2,session:e.$solid.session},(()=>[B("div",ae,[W(z(l),{text:e.$td("solid.loggedIn",{userName:e.$solid.user.name??e.$solid.user.webId,userWebId:e.$solid.user.webId},"You are logged in as [{userName}]({userWebId})")},null,8,["text"]),W(z(u),{onClick:i[0]||(i[0]=t=>e.$solid.logout())},{default:D((()=>[M(Y(e.$td("solid.logout","Logout")),1)])),_:1})])])):G(e.$slots,"logged-out",{key:3},(()=>[B("div",le,[W(z(c),{form:z(t),class:"flex",onSubmit:i[1]||(i[1]=i=>e.$solid.login(z(t).url))},{default:D((()=>[W(z(d),{name:"url","aria-label":e.$td("solid.url","Login url"),placeholder:e.$td("solid.placeholder","https://...")},null,8,["aria-label","placeholder"]),W(z(u),{submit:""},{default:D((()=>[M(Y(e.$td("solid.login","Login")),1)])),_:1})])),_:1},8,["form"]),e.$solid.wasLoggedIn?(q(),H(z(u),{key:0,class:"mt-3",onClick:i[2]||(i[2]=t=>e.$solid.reconnect(!0))},{default:D((()=>[M(Y(e.$td("solid.reconnect","Reconnect")),1)])),_:1})):N("v-if",!0),e.$solid.previousSession?.error?(q(),H(z(l),{key:1,class:"mt-1 self-center text-sm text-red-800",text:e.$td("solid.previousLoginError","Previous login attempt failed")},null,8,["text"])):N("v-if",!0)])]))]))}});ue.__file="src/components/AGSolidStatus.vue";const ce={$solid:ne};function de(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{async install(t){w(),te({...X,...e.authenticators??{}}),Z(ee(e.defaultAuthenticator??"inrupt")),await h(t,ce)}}}export{ue as AGSolidStatus,AuthenticationCancelledError,J as ContainerAlreadyInUse,ne as Solid,X as authenticators,de as default,ee as getAuthenticator,ie as registerAuthenticator,te as registerAuthenticators,Z as setDefaultAuthenticator};
|
|
2
|
-
//# sourceMappingURL=aerogel-plugin-solid.esm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aerogel-plugin-solid.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/noeldemartin.config.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<slot v-if="$solid.loginStale" name="login-stale">
|
|
4
|
-
<AGMarkdown :text="$td('solid.loginStale', 'This is taking too long...')" />
|
|
5
|
-
</slot>
|
|
6
|
-
|
|
7
|
-
<slot v-if="$solid.loginOngoing" name="login-ongoing">
|
|
8
|
-
<AGMarkdown :text="$td('ui.loading', 'Loading...')" />
|
|
9
|
-
</slot>
|
|
10
|
-
|
|
11
|
-
<slot v-else-if="$solid.isLoggedIn()" name="logged-in" :session="$solid.session">
|
|
12
|
-
<div class="flex flex-col gap-3">
|
|
13
|
-
<AGMarkdown
|
|
14
|
-
:text="
|
|
15
|
-
$td(
|
|
16
|
-
'solid.loggedIn',
|
|
17
|
-
{
|
|
18
|
-
userName: $solid.user.name ?? $solid.user.webId,
|
|
19
|
-
userWebId: $solid.user.webId,
|
|
20
|
-
},
|
|
21
|
-
'You are logged in as [{userName}]({userWebId})'
|
|
22
|
-
)
|
|
23
|
-
"
|
|
24
|
-
/>
|
|
25
|
-
<AGButton @click="$solid.logout()">
|
|
26
|
-
{{ $td('solid.logout', 'Logout') }}
|
|
27
|
-
</AGButton>
|
|
28
|
-
</div>
|
|
29
|
-
</slot>
|
|
30
|
-
|
|
31
|
-
<slot v-else name="logged-out">
|
|
32
|
-
<div class="flex flex-col">
|
|
33
|
-
<AGForm :form="form" class="flex" @submit="$solid.login(form.url)">
|
|
34
|
-
<AGInput
|
|
35
|
-
name="url"
|
|
36
|
-
:aria-label="$td('solid.url', 'Login url')"
|
|
37
|
-
:placeholder="$td('solid.placeholder', 'https://...')"
|
|
38
|
-
/>
|
|
39
|
-
<AGButton submit>
|
|
40
|
-
{{ $td('solid.login', 'Login') }}
|
|
41
|
-
</AGButton>
|
|
42
|
-
</AGForm>
|
|
43
|
-
<AGButton v-if="$solid.wasLoggedIn" class="mt-3" @click="$solid.reconnect(true)">
|
|
44
|
-
{{ $td('solid.reconnect', 'Reconnect') }}
|
|
45
|
-
</AGButton>
|
|
46
|
-
<AGMarkdown
|
|
47
|
-
v-if="$solid.previousSession?.error"
|
|
48
|
-
class="mt-1 self-center text-sm text-red-800"
|
|
49
|
-
:text="$td('solid.previousLoginError', 'Previous login attempt failed')"
|
|
50
|
-
/>
|
|
51
|
-
</div>
|
|
52
|
-
</slot>
|
|
53
|
-
</div>
|
|
54
|
-
</template>
|
|
55
|
-
|
|
56
|
-
<script setup lang="ts">
|
|
57
|
-
import { AGButton, AGForm, AGInput, AGMarkdown, requiredStringInput, useForm } from '@aerogel/core';
|
|
58
|
-
|
|
59
|
-
const form = useForm({ url: requiredStringInput() });
|
|
60
|
-
</script>
|
package/src/main.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { bootServices } from '@aerogel/core';
|
|
2
|
-
import { bootSolidModels } from 'soukai-solid';
|
|
3
|
-
import type { Plugin } from '@aerogel/core';
|
|
4
|
-
|
|
5
|
-
import Solid from '@/services/Solid';
|
|
6
|
-
import {
|
|
7
|
-
authenticators as baseAuthenticators,
|
|
8
|
-
getAuthenticator,
|
|
9
|
-
registerAuthenticators,
|
|
10
|
-
setDefaultAuthenticator,
|
|
11
|
-
} from '@/auth';
|
|
12
|
-
import type Authenticator from '@/auth/Authenticator';
|
|
13
|
-
import type { AuthenticatorName } from '@/auth';
|
|
14
|
-
|
|
15
|
-
const services = { $solid: Solid };
|
|
16
|
-
|
|
17
|
-
export { Solid };
|
|
18
|
-
export * from './auth';
|
|
19
|
-
export * from './components';
|
|
20
|
-
export * from './errors';
|
|
21
|
-
|
|
22
|
-
export interface Options {
|
|
23
|
-
authenticators?: Record<string, Authenticator>;
|
|
24
|
-
defaultAuthenticator?: AuthenticatorName;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type SolidServices = typeof services;
|
|
28
|
-
|
|
29
|
-
export default function solid(options: Options = {}): Plugin {
|
|
30
|
-
return {
|
|
31
|
-
async install(app) {
|
|
32
|
-
bootSolidModels();
|
|
33
|
-
registerAuthenticators({ ...baseAuthenticators, ...(options.authenticators ?? {}) });
|
|
34
|
-
setDefaultAuthenticator(getAuthenticator(options.defaultAuthenticator ?? 'inrupt'));
|
|
35
|
-
|
|
36
|
-
await bootServices(app, services);
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
declare module '@vue/runtime-core' {
|
|
42
|
-
interface ComponentCustomProperties extends SolidServices {}
|
|
43
|
-
}
|