Skip to content

Commit 9f576d2

Browse files
authored
Merge pull request #18 from pdsinterop/feature/bootloader
Feature/bootloader
2 parents a0753be + b618572 commit 9f576d2

5 files changed

Lines changed: 220 additions & 6 deletions

File tree

frontend/bootloader.html

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
<!DOCTYPE HTML>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<!-- Component CSS -->
6+
<style>
7+
8+
</style>
9+
<!-- /Component CSS -->
10+
<!-- Page CSS -->
11+
<style>
12+
13+
</style>
14+
<!-- /Page CSS -->
15+
<!-- Head HTML -->
16+
<!-- metro (baseComponent/metro) -->
17+
<script src="https://cdn.jsdelivr.net/npm/@muze-nl/metro@0.6.19/dist/browser.js"></script>
18+
<script src="https://cdn.jsdelivr.net/npm/@muze-nl/oldm@0.3.6/dist/oldm.js"></script>
19+
<script src="https://cdn.jsdelivr.net/npm/@muze-nl/metro-oauth2@0.7.4/dist/browser.js"></script>
20+
<script src="https://cdn.jsdelivr.net/npm/@muze-nl/metro-oidc@0.5.3/dist/browser.js"></script>
21+
<!-- /Head HTML -->
22+
<script>
23+
var simplyDataApi = {};
24+
var simplyApp = {};
25+
window.addEventListener("simply-content-loaded", function() {
26+
simply.bind = false;
27+
/* Raw API */
28+
var simplyRawApi = {
29+
30+
};
31+
/* End of Raw API */
32+
/* Data API */
33+
simplyDataApi = {
34+
// component/solid-preferences
35+
"getPreferences" : async function(webID){
36+
37+
let issuer = ""
38+
let profileTurtle
39+
40+
const context = oldm.context({
41+
prefixes: {
42+
'ldp': 'http://www.w3.org/ns/ldp#',
43+
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
44+
'dct': 'http://purl.org/dc/terms/',
45+
'stat': 'http://www.w3.org/ns/posix/stat#',
46+
'turtle': 'http://www.w3.org/ns/iana/media-types/text/turtle#',
47+
'schem': 'https://schema.org/',
48+
'solid': 'http://www.w3.org/ns/solid/terms#',
49+
'acl': 'http://www.w3.org/ns/auth/acl#',
50+
'pims': 'http://www.w3.org/ns/pim/space#',
51+
'vcard': 'http://www.w3.org/2006/vcard/ns#',
52+
'foaf': 'http://xmlns.com/foaf/0.1/'
53+
},
54+
parser: oldm.n3Parser,
55+
writer: oldm.n3Writer
56+
})
57+
58+
//fetch profile to retrieve issuer
59+
const profileURL = webID;
60+
try {
61+
const responseProfile = await fetch(profileURL);
62+
if (!responseProfile.ok) {
63+
throw new Error(`Response status: ${responseProfile.status}`);
64+
}
65+
profileTurtle = await responseProfile.text();
66+
} catch (error) {
67+
console.error(error.message);
68+
}
69+
70+
let podContent = context.parse(profileTurtle, webID, 'text/turtle')
71+
72+
issuer = podContent.primary?.solid$oidcIssuer?.id
73+
let preferenceFileURL = podContent.primary?.pims$preferencesFile?.id
74+
75+
const oidcOptions = {
76+
// authorize_callback: metro.oauth2.authorizePopup,
77+
force_authorization: true,
78+
client_info: {
79+
client_name: 'Solid Bootloader',
80+
redirect_uris: [
81+
window.location.origin + window.location.pathname
82+
]
83+
},
84+
issuer: issuer
85+
}
86+
if (window.location.protocol !== "https") {
87+
// needed to allow app.simplyapp:// as redirect uri
88+
oidcOptions['client_info']['application_type'] = 'native';
89+
}
90+
91+
let client = metro.client().with(metro.oidc.oidcmw(oidcOptions))
92+
93+
let preferenceResponse = await client.get(preferenceFileURL)
94+
95+
if (!preferenceResponse.ok) {
96+
throw new Error(preferenceResponse.status+':'+preferenceResponse.statusText)
97+
}
98+
99+
const preferenceTurtle = await preferenceResponse.text()
100+
let preferenceOLDM = context.parse(preferenceTurtle, preferenceFileURL, 'text/turtle')
101+
102+
return preferenceOLDM
103+
104+
},
105+
// component/bootloader
106+
"appLocation" : async function(webID){
107+
let preferenceOLDM = await simplyDataApi.getPreferences(webID)
108+
if (
109+
preferenceOLDM.subjects[webID] &&
110+
preferenceOLDM.subjects[webID].solid$launcher
111+
) {
112+
return preferenceOLDM.subjects[webID].solid$launcher.id
113+
} else {
114+
return "https://solid-launcher.dev.muze.nl/"
115+
}
116+
}
117+
};
118+
/* End of Data API */
119+
simplyApp = simply.app({
120+
/* Actions */
121+
actions: {
122+
// component/bootloader
123+
"getLauncherLocation" : async function (webID){
124+
let appLauncherPath = await simplyDataApi.appLocation(webID)
125+
return appLauncherPath
126+
}
127+
},
128+
/* /Actions */
129+
/* Commands */
130+
commands: {
131+
132+
},
133+
/* /Commands */
134+
/* Keyboard shortcuts */
135+
keyboard: {
136+
137+
},
138+
/* /Keyboard shortcuts */
139+
/* Routes */
140+
routes: {
141+
// page/home
142+
"#autologin/:webID" : async function(params) {
143+
let webID = params.webID
144+
webID = decodeURIComponent(webID)
145+
localStorage['bootloader:webID'] = webID
146+
let appLauncherPath = await simplyApp.actions.getLauncherLocation(webID)
147+
document.location.href = appLauncherPath + "#autologin/" + encodeURIComponent(webID)
148+
},
149+
// page/home
150+
"/" : async function() {
151+
if (
152+
document.location.search.match("code") ||
153+
document.location.search.match("state")
154+
) {
155+
let webID = localStorage['bootloader:webID']
156+
let appLauncherPath = await simplyApp.actions.getLauncherLocation(webID)
157+
document.location.href = appLauncherPath + "#autologin/" + encodeURIComponent(webID)
158+
}
159+
}
160+
}
161+
/* /Routes */
162+
});
163+
});
164+
function clone(ob) {
165+
return JSON.parse(JSON.stringify(ob));
166+
}
167+
function updateDataSource(name) {
168+
document.querySelectorAll('[data-simply-data="'+name+'"]').forEach(function(list) {
169+
editor.list.applyDataSource(list, name);
170+
list.dataBindingPaused = 0;
171+
});
172+
}
173+
</script>
174+
</head>
175+
<body>
176+
<!-- Body HTML -->
177+
178+
<!-- /Body HTML -->
179+
<!-- Component HTML templates -->
180+
181+
<!-- /Component HTML templates -->
182+
<div class="main" data-simply-field="page" data-simply-content="template">
183+
<!-- Page HTML templates -->
184+
185+
<!-- /Page HTML templates -->
186+
</div>
187+
<script src="https://unpkg.com/simplyview@3.5.5/dist/simply.everything.js"></script>
188+
<script src="https://canary.simplyedit.io/1/simply-edit.js" data-simply-storage="none" data-api-key="simply-edit-0011"></script>
189+
<script>
190+
/* Transformers */
191+
editor.transformers = {
192+
193+
};
194+
/* /Transformers */
195+
</script>
196+
<script>
197+
/* Sorters */
198+
editor.sorters = {
199+
200+
};
201+
/* /Sorters */
202+
</script>
203+
<script>
204+
window.addEventListener("simply-content-loaded", function() {
205+
/* Data sources */
206+
207+
/* /Data sources */
208+
});
209+
</script>
210+
<!-- Foot HTML -->
211+
212+
<!-- /Foot HTML -->
213+
</body>
214+
</html>

lib/Routes/Account.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static function requireLoggedInUser() {
2727

2828
public static function respondToDashboard() {
2929
$user = User::getUser(Session::getLoggedInUser());
30-
echo "Logged in as " . $user['webId'];
30+
include_once(FRONTENDDIR . "bootloader.html");
3131
}
3232

3333
public static function respondToLogout() {
@@ -170,8 +170,9 @@ public static function respondToLogin() {
170170
}
171171
if (User::checkPassword($_POST['username'], $_POST['password'])) {
172172
Session::start($_POST['username']);
173+
$user = User::getUser($_POST['username']);
173174
if (!isset($_POST['redirect_uri']) || $_POST['redirect_uri'] === '') {
174-
header("Location: /dashboard/");
175+
header("Location: /dashboard/#autologin/" . urlencode($user['webId']));
175176
exit();
176177
}
177178
header("Location: " . urldecode($_POST['redirect_uri'])); // FIXME: Do we need to harden this?

lib/Routes/SolidStorage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static function respondToStorage() {
4343
$owner = StorageServer::getOwner();
4444

4545
$allowedClients = $owner['allowedClients'] ?? [];
46-
$allowedOrigins = [];
46+
$allowedOrigins = TRUSTED_APPS ?? [];
4747
foreach ($allowedClients as $clientId) {
4848
$clientRegistration = ClientRegistration::getRegistration($clientId);
4949
if (isset($clientRegistration['client_name'])) {

lib/Routes/SolidUserProfile.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static function respondToProfile() {
4646
$owner = ProfileServer::getOwner();
4747

4848
$allowedClients = $owner['allowedClients'] ?? [];
49-
$allowedOrigins = [];
49+
$allowedOrigins = TRUSTED_APPS ?? [];
5050
foreach ($allowedClients as $clientId) {
5151
$clientRegistration = ClientRegistration::getRegistration($clientId);
5252
if (isset($clientRegistration['client_name'])) {

lib/StorageServer.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,13 @@ public static function generateDefaultPreferences() {
237237
@prefix : <#>.
238238
@prefix sp: <http://www.w3.org/ns/pim/space#>.
239239
@prefix dct: <http://purl.org/dc/terms/>.
240-
@prefix profile: <$webId>.
241240
@prefix solid: <http://www.w3.org/ns/solid/terms#>.
242241
243242
<>
244243
a sp:ConfigurationFile;
245244
dct:title "Preferences file".
246245
247-
profile:me
246+
<$webId>
248247
a solid:Developer;
249248
solid:privateTypeIndex <privateTypeIndex.ttl>;
250249
solid:publicTypeIndex <publicTypeIndex.ttl>.

0 commit comments

Comments
 (0)