refactored boot and fixed corresponding calls in social and storage
This commit is contained in:
parent
a9b018b39f
commit
918edda1f6
|
@ -0,0 +1,248 @@
|
||||||
|
/**
|
||||||
|
* D4Science boot component that handles keykloak authz
|
||||||
|
* <d4s-boot-2
|
||||||
|
* /@url: keycloak url, for example: https://accounts.pre.d4science.org/auth]
|
||||||
|
* /@realm: is the realm [defaults to: d4science]
|
||||||
|
* /@gateway: is the client id, for example: "pre.d4science.org"
|
||||||
|
* /@context: is the audience, for example: "%2Fpred4s%2Fpreprod%2FpreVRE"
|
||||||
|
* /@redirect-url: where to go on logout
|
||||||
|
*/
|
||||||
|
window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
||||||
|
|
||||||
|
#keycloak = null
|
||||||
|
#authorization = null
|
||||||
|
#url = null
|
||||||
|
#realm = "d4science"
|
||||||
|
#clientId = null
|
||||||
|
#redirectUrl = null
|
||||||
|
#audience = null
|
||||||
|
|
||||||
|
// loading attempts nr and timer between attempts
|
||||||
|
#attempts = 6
|
||||||
|
#timer = 500
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
if (typeof Keycloak === 'undefined') {
|
||||||
|
const script = document.createElement('script')
|
||||||
|
script.src = this.#url + '/js/keycloak.js'
|
||||||
|
script.type = 'text/javascript'
|
||||||
|
script.addEventListener('load', () => {
|
||||||
|
this.initKeycloak()
|
||||||
|
})
|
||||||
|
document.head.appendChild(script)
|
||||||
|
} else {
|
||||||
|
this.initKeycloak()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initKeycloak() {
|
||||||
|
this.#keycloak = new Keycloak({
|
||||||
|
url: this.#url,
|
||||||
|
realm: this.#realm,
|
||||||
|
clientId: this.#clientId
|
||||||
|
})
|
||||||
|
|
||||||
|
const keycloak = this.#keycloak
|
||||||
|
const url = this.#url
|
||||||
|
|
||||||
|
keycloak.init({
|
||||||
|
onLoad: 'login-required'
|
||||||
|
, checkLoginIframe: false
|
||||||
|
|
||||||
|
}).then((authenticated) => {
|
||||||
|
console.log(authenticated ? 'Authenticated in ' + this.#realm : 'Not authenticated')
|
||||||
|
if (typeof KeycloakAuthorization === 'undefined') {
|
||||||
|
const authz = document.createElement('script')
|
||||||
|
authz.src = url + '/js/keycloak-authz.js'
|
||||||
|
authz.type = 'text/javascript'
|
||||||
|
authz.addEventListener('load', () => {
|
||||||
|
this.#authorization = new KeycloakAuthorization(keycloak)
|
||||||
|
})
|
||||||
|
document.head.appendChild(authz)
|
||||||
|
} else {
|
||||||
|
this.#authorization = new KeycloakAuthorization(keycloak)
|
||||||
|
}
|
||||||
|
//console.log("expires: " + this.expirationDate(keycloak.tokenParsed.exp))
|
||||||
|
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.error("Failed to initialize d4science boot component")
|
||||||
|
console.error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
parseJwt(token) {
|
||||||
|
var base64Url = token.split('.')[1]
|
||||||
|
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
|
||||||
|
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
|
||||||
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
|
||||||
|
}).join(''))
|
||||||
|
|
||||||
|
return JSON.parse(jsonPayload);
|
||||||
|
}
|
||||||
|
|
||||||
|
expirationDate(utc) {
|
||||||
|
let d = new Date(0)
|
||||||
|
d.setUTCSeconds(utc)
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
checkContext() {
|
||||||
|
const parseJwt = this.parseJwt
|
||||||
|
const expDt = this.expirationDate
|
||||||
|
const audience = encodeURIComponent(this.#audience)
|
||||||
|
this.#authorization.entitlement(audience).then(function (rpt) {
|
||||||
|
// onGrant callback function.
|
||||||
|
// If authorization was successful you'll receive an RPT
|
||||||
|
// with the necessary permissions to access the resource server
|
||||||
|
console.log(rpt)
|
||||||
|
//console.log("rpt expires: " + expDt(parseJwt(rpt).exp))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
service(endpoint, method, params, onSuccess, onForbidden) {
|
||||||
|
if (this.#authorization == null) {
|
||||||
|
if (this.#attempts-- > 0) {
|
||||||
|
setTimeout(() => this.service(endpoint, method, params, onSuccess, onForbidden), this.#timer)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
console.error("Impossible to initialize D4Science authorization component")
|
||||||
|
throw "Fatal error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.#keycloak.updateToken(30).then(() => {
|
||||||
|
const audience = encodeURIComponent(this.#audience)
|
||||||
|
this.#authorization.entitlement(audience).then(function (rpt) {
|
||||||
|
var req = new XMLHttpRequest()
|
||||||
|
req.open(method, endpoint, true)
|
||||||
|
req.setRequestHeader('Accept', 'application/json')
|
||||||
|
req.setRequestHeader('Authorization', 'Bearer ' + rpt)
|
||||||
|
|
||||||
|
req.onreadystatechange = function () {
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
if (req.status == 200) {
|
||||||
|
onSuccess(req.response)
|
||||||
|
} else if (req.status == 403) {
|
||||||
|
onForbidden(req.statusText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.send(params)
|
||||||
|
})
|
||||||
|
}).catch(function() {
|
||||||
|
onForbidden('Failed to refresh token')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
download(endpoint, name) {
|
||||||
|
this.#keycloak.updateToken(30).then(() => {
|
||||||
|
const audience = encodeURIComponent(this.#audience)
|
||||||
|
this.#authorization.entitlement(audience).then(function (rpt) {
|
||||||
|
fetch(endpoint, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer ' + rpt
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.blob())
|
||||||
|
.then(blob => {
|
||||||
|
const objectURL = URL.createObjectURL(blob)
|
||||||
|
var tmplnk = document.createElement("a")
|
||||||
|
tmplnk.download = name
|
||||||
|
tmplnk.href = objectURL
|
||||||
|
document.body.appendChild(tmplnk)
|
||||||
|
tmplnk.click()
|
||||||
|
document.body.removeChild(tmplnk)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}).catch(function() {
|
||||||
|
onForbidden('Failed to refresh token')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
if (this.#keycloak) {
|
||||||
|
if (!this.#redirectUrl) {
|
||||||
|
console.error("Missing required @redirectUrl attribute in d4s-boot")
|
||||||
|
} else {
|
||||||
|
this.#keycloak.logout({
|
||||||
|
redirectUri: this.#redirectUrl
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get observedAttributes() {
|
||||||
|
return ["url", "realm", "gateway", "redirect-url", "context"];
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
|
if (oldValue !== newValue) {
|
||||||
|
switch (name) {
|
||||||
|
case "url":
|
||||||
|
this.#url = newValue
|
||||||
|
break
|
||||||
|
case "realm":
|
||||||
|
this.#realm = newValue
|
||||||
|
break
|
||||||
|
case "gateway":
|
||||||
|
this.#clientId = newValue
|
||||||
|
break
|
||||||
|
case "redirect-url":
|
||||||
|
this.#redirectUrl = newValue
|
||||||
|
break
|
||||||
|
case "context":
|
||||||
|
this.#audience = newValue
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get url() {
|
||||||
|
return this.#url
|
||||||
|
}
|
||||||
|
|
||||||
|
set url(url) {
|
||||||
|
this.#url = url
|
||||||
|
this.setAttribute("url", url)
|
||||||
|
}
|
||||||
|
|
||||||
|
get realm() {
|
||||||
|
return this.#realm
|
||||||
|
}
|
||||||
|
|
||||||
|
set realm(realm) {
|
||||||
|
this.#realm = realm
|
||||||
|
this.setAttribute("realm", realm)
|
||||||
|
}
|
||||||
|
|
||||||
|
get clientId() {
|
||||||
|
return this.#clientId
|
||||||
|
}
|
||||||
|
|
||||||
|
set clientId(clientId) {
|
||||||
|
this.#clientId = clientId
|
||||||
|
this.setAttribute("gateway", clientId)
|
||||||
|
}
|
||||||
|
|
||||||
|
get redirectUrl() {
|
||||||
|
return this.#redirectUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
set redirectUrl(redirectUrl) {
|
||||||
|
this.#redirectUrl = redirectUrl
|
||||||
|
this.setAttribute("redirect-url", redirectUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
get context() {
|
||||||
|
return this.#audience
|
||||||
|
}
|
||||||
|
|
||||||
|
set context(context) {
|
||||||
|
this.#audience = context
|
||||||
|
this.setAttribute("context", context)
|
||||||
|
}
|
||||||
|
})
|
256
boot/d4s-boot.js
256
boot/d4s-boot.js
|
@ -1,12 +1,3 @@
|
||||||
/**
|
|
||||||
* D4Science boot component that handles keykloak authz
|
|
||||||
* <d4s-boot-2
|
|
||||||
* /@url: keycloak url, for example: https://accounts.pre.d4science.org/auth]
|
|
||||||
* /@realm: is the realm [defaults to: d4science]
|
|
||||||
* /@gateway: is the client id, for example: "pre.d4science.org"
|
|
||||||
* /@context: is the audience, for example: "%2Fpred4s%2Fpreprod%2FpreVRE"
|
|
||||||
* /@redirect-url: where to go on logout
|
|
||||||
*/
|
|
||||||
window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
||||||
|
|
||||||
#keycloak = null
|
#keycloak = null
|
||||||
|
@ -18,25 +9,60 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
||||||
#audience = null
|
#audience = null
|
||||||
|
|
||||||
// loading attempts nr and timer between attempts
|
// loading attempts nr and timer between attempts
|
||||||
#attempts = 6
|
//#attempts = 6
|
||||||
#timer = 500
|
//#timer = 500
|
||||||
|
|
||||||
|
#locked = true
|
||||||
|
#queue = []
|
||||||
|
#interval = null
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock(){
|
||||||
|
this.#locked = false
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback(){
|
connectedCallback(){
|
||||||
|
|
||||||
|
this.startStateChecker()
|
||||||
|
|
||||||
|
this.loadKeycloak().then(()=>{
|
||||||
|
|
||||||
|
console.log("Keycloak loaded")
|
||||||
|
return this.initKeycloak()
|
||||||
|
|
||||||
|
}).then((authenticated)=>{
|
||||||
|
|
||||||
|
if(!authenticated) throw "Failed to authenticate";
|
||||||
|
|
||||||
|
console.log("Keycloak initialized and user authenticated")
|
||||||
|
return this.loadKeycloakAuthorization()
|
||||||
|
|
||||||
|
}).then(()=>{
|
||||||
|
|
||||||
|
this.#authorization = new KeycloakAuthorization(this.#keycloak)
|
||||||
|
console.log("Keycloak authorization loaded and initialized", this.#authorization)
|
||||||
|
this.unlock()
|
||||||
|
|
||||||
|
}).catch(err=>{
|
||||||
|
console.error("Unable to initialize Keycloak",err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
loadKeycloak(){
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
if (typeof Keycloak === 'undefined') {
|
if (typeof Keycloak === 'undefined') {
|
||||||
const script = document.createElement('script')
|
const script = document.createElement('script')
|
||||||
script.src = this.#url + '/js/keycloak.js'
|
script.src = this.#url + '/js/keycloak.js'
|
||||||
script.type = 'text/javascript'
|
script.type = 'text/javascript'
|
||||||
script.addEventListener('load', () => {
|
script.addEventListener('load', resolve)
|
||||||
this.initKeycloak()
|
|
||||||
})
|
|
||||||
document.head.appendChild(script)
|
document.head.appendChild(script)
|
||||||
} else {
|
} else {
|
||||||
this.initKeycloak()
|
resolve()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
initKeycloak(){
|
initKeycloak(){
|
||||||
|
@ -46,34 +72,54 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
||||||
clientId: this.#clientId
|
clientId: this.#clientId
|
||||||
})
|
})
|
||||||
|
|
||||||
const keycloak = this.#keycloak
|
return this.#keycloak.init({onLoad: 'login-required', checkLoginIframe: false })
|
||||||
const url = this.#url
|
}
|
||||||
|
|
||||||
keycloak.init({
|
loadKeycloakAuthorization(){
|
||||||
onLoad: 'login-required'
|
return new Promise((resolve, reject)=>{
|
||||||
, checkLoginIframe: false
|
|
||||||
|
|
||||||
}).then((authenticated) => {
|
|
||||||
console.log(authenticated ? 'Authenticated in ' + this.#realm : 'Not authenticated')
|
|
||||||
if (typeof KeycloakAuthorization === 'undefined') {
|
if (typeof KeycloakAuthorization === 'undefined') {
|
||||||
const authz = document.createElement('script')
|
const authz = document.createElement('script')
|
||||||
authz.src = url + '/js/keycloak-authz.js'
|
authz.src = this.#url + '/js/keycloak-authz.js'
|
||||||
authz.type = 'text/javascript'
|
authz.type = 'text/javascript'
|
||||||
authz.addEventListener('load', () => {
|
authz.addEventListener('load', resolve)
|
||||||
this.#authorization = new KeycloakAuthorization(keycloak)
|
|
||||||
})
|
|
||||||
document.head.appendChild(authz)
|
document.head.appendChild(authz)
|
||||||
} else {
|
} else {
|
||||||
this.#authorization = new KeycloakAuthorization(keycloak)
|
resolve()
|
||||||
}
|
}
|
||||||
//console.log("expires: " + this.expirationDate(keycloak.tokenParsed.exp))
|
|
||||||
|
|
||||||
}).catch(function(err) {
|
|
||||||
console.error("Failed to initialize d4science boot component")
|
|
||||||
console.error(err)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startStateChecker(){
|
||||||
|
this.#interval = window.setInterval(()=>{
|
||||||
|
if(this.#locked){
|
||||||
|
console.log("Still locked. Currently has " + this.#queue.length + " pending requests.")
|
||||||
|
}else{
|
||||||
|
if(this.#queue.length > 0){
|
||||||
|
const audience = encodeURIComponent(this.#audience)
|
||||||
|
console.log("Updating token")
|
||||||
|
this.#keycloak.updateToken(30).then(()=>{
|
||||||
|
console.log("Checking entitlement")
|
||||||
|
return this.#authorization.entitlement(audience)
|
||||||
|
}).then(
|
||||||
|
rpt => {
|
||||||
|
console.log("Authorized")
|
||||||
|
//transform all queued requests to fetches
|
||||||
|
console.log("All pending requests to promises")
|
||||||
|
let promises = this.#queue.map(r => {
|
||||||
|
r.request.headers["Authorization"] = "Bearer " + rpt
|
||||||
|
return r.resolve( fetch(r.url, r.request) )
|
||||||
|
})
|
||||||
|
//clear queue
|
||||||
|
this.#queue = []
|
||||||
|
console.log("Resolving all fetches")
|
||||||
|
return Promise.all(promises)
|
||||||
|
}
|
||||||
|
).catch(err => alert("Unable to make calls: " + err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
parseJwt(token) {
|
parseJwt(token) {
|
||||||
var base64Url = token.split('.')[1]
|
var base64Url = token.split('.')[1]
|
||||||
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
|
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
|
||||||
|
@ -103,52 +149,25 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
service(endpoint, method, params, onSuccess, onForbidden) {
|
secureFetch(url, request){
|
||||||
if (this.#authorization == null) {
|
const p = new Promise((resolve, reject)=>{
|
||||||
if (this.#attempts-- > 0) {
|
let req = request ? request : {}
|
||||||
setTimeout(() => this.service(endpoint, method, params, onSuccess, onForbidden), this.#timer)
|
if("headers" in req){
|
||||||
return
|
req.headers["Authorization"] = null
|
||||||
} else {
|
} else {
|
||||||
console.error("Impossible to initialize D4Science authorization component")
|
req.headers = { "Authorization" : null}
|
||||||
throw "Fatal error"
|
|
||||||
}
|
}
|
||||||
}
|
console.log("Queued request to url ", url)
|
||||||
this.#keycloak.updateToken(30).then(() => {
|
this.#queue.push({ url : url, request : req, resolve : resolve, reject : reject})
|
||||||
const audience = encodeURIComponent(this.#audience)
|
|
||||||
this.#authorization.entitlement(audience).then(function (rpt) {
|
|
||||||
var req = new XMLHttpRequest()
|
|
||||||
req.open(method, endpoint, true)
|
|
||||||
req.setRequestHeader('Accept', 'application/json')
|
|
||||||
req.setRequestHeader('Authorization', 'Bearer ' + rpt)
|
|
||||||
|
|
||||||
req.onreadystatechange = function () {
|
|
||||||
if (req.readyState == 4) {
|
|
||||||
if (req.status == 200) {
|
|
||||||
onSuccess(req.response)
|
|
||||||
} else if (req.status == 403) {
|
|
||||||
onForbidden(req.statusText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.send(params)
|
|
||||||
})
|
|
||||||
}).catch(function() {
|
|
||||||
onForbidden('Failed to refresh token')
|
|
||||||
})
|
})
|
||||||
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
download(endpoint, name) {
|
download(url, name) {
|
||||||
this.#keycloak.updateToken(30).then(() => {
|
this.secureFetch(url).then(reply=>{
|
||||||
const audience = encodeURIComponent(this.#audience)
|
if(reply.status !== 200) throw "Unable to download";
|
||||||
this.#authorization.entitlement(audience).then(function (rpt) {
|
return reply.blob()
|
||||||
fetch(endpoint, {
|
}).then(blob=>{
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Bearer ' + rpt
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.blob())
|
|
||||||
.then(blob => {
|
|
||||||
const objectURL = URL.createObjectURL(blob)
|
const objectURL = URL.createObjectURL(blob)
|
||||||
var tmplnk = document.createElement("a")
|
var tmplnk = document.createElement("a")
|
||||||
tmplnk.download = name
|
tmplnk.download = name
|
||||||
|
@ -156,11 +175,7 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
||||||
document.body.appendChild(tmplnk)
|
document.body.appendChild(tmplnk)
|
||||||
tmplnk.click()
|
tmplnk.click()
|
||||||
document.body.removeChild(tmplnk)
|
document.body.removeChild(tmplnk)
|
||||||
})
|
}).catch(err=>alert(err)
|
||||||
})
|
|
||||||
}).catch(function() {
|
|
||||||
onForbidden('Failed to refresh token')
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logout() {
|
logout() {
|
||||||
|
@ -246,3 +261,86 @@ window.customElements.define('d4s-boot-2', class extends HTMLElement {
|
||||||
this.setAttribute("context", context)
|
this.setAttribute("context", context)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/*connectedCallback() {
|
||||||
|
if (typeof Keycloak === 'undefined') {
|
||||||
|
const script = document.createElement('script')
|
||||||
|
script.src = this.#url + '/js/keycloak.js'
|
||||||
|
script.type = 'text/javascript'
|
||||||
|
script.addEventListener('load', () => {
|
||||||
|
this.initKeycloak()
|
||||||
|
})
|
||||||
|
document.head.appendChild(script)
|
||||||
|
} else {
|
||||||
|
this.initKeycloak()
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*initKeycloak() {
|
||||||
|
this.#keycloak = new Keycloak({
|
||||||
|
url: this.#url,
|
||||||
|
realm: this.#realm,
|
||||||
|
clientId: this.#clientId
|
||||||
|
})
|
||||||
|
|
||||||
|
const keycloak = this.#keycloak
|
||||||
|
const url = this.#url
|
||||||
|
|
||||||
|
keycloak.init({
|
||||||
|
onLoad: 'login-required'
|
||||||
|
, checkLoginIframe: false
|
||||||
|
|
||||||
|
}).then((authenticated) => {
|
||||||
|
console.log(authenticated ? 'Authenticated in ' + this.#realm : 'Not authenticated')
|
||||||
|
if (typeof KeycloakAuthorization === 'undefined') {
|
||||||
|
const authz = document.createElement('script')
|
||||||
|
authz.src = url + '/js/keycloak-authz.js'
|
||||||
|
authz.type = 'text/javascript'
|
||||||
|
authz.addEventListener('load', () => {
|
||||||
|
this.#authorization = new KeycloakAuthorization(keycloak)
|
||||||
|
})
|
||||||
|
document.head.appendChild(authz)
|
||||||
|
} else {
|
||||||
|
this.#authorization = new KeycloakAuthorization(keycloak)
|
||||||
|
}
|
||||||
|
//console.log("expires: " + this.expirationDate(keycloak.tokenParsed.exp))
|
||||||
|
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.error("Failed to initialize d4science boot component")
|
||||||
|
|
||||||
|
})
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*service(endpoint, method, params, onSuccess, onForbidden) {
|
||||||
|
if (this.#authorization == null) {
|
||||||
|
if (this.#attempts-- > 0) {
|
||||||
|
setTimeout(() => this.service(endpoint, method, params, onSuccess, onForbidden), this.#timer)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
console.error("Impossible to initialize D4Science authorization component")
|
||||||
|
throw "Fatal error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.#keycloak.updateToken(30).then(() => {
|
||||||
|
const audience = encodeURIComponent(this.#audience)
|
||||||
|
this.#authorization.entitlement(audience).then(function (rpt) {
|
||||||
|
var req = new XMLHttpRequest()
|
||||||
|
req.open(method, endpoint, true)
|
||||||
|
req.setRequestHeader('Accept', 'application/json')
|
||||||
|
req.setRequestHeader('Authorization', 'Bearer ' + rpt)
|
||||||
|
|
||||||
|
req.onreadystatechange = function () {
|
||||||
|
if (req.readyState == 4) {
|
||||||
|
if (req.status == 200) {
|
||||||
|
onSuccess(req.response)
|
||||||
|
} else if (req.status == 403) {
|
||||||
|
onForbidden(req.statusText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.send(params)
|
||||||
|
})
|
||||||
|
}).catch(function() {
|
||||||
|
onForbidden('Failed to refresh token')
|
||||||
|
})
|
||||||
|
}*/
|
||||||
|
|
|
@ -3,31 +3,46 @@
|
||||||
*/
|
*/
|
||||||
window.customElements.define('d4s-social-posts', class extends HTMLElement {
|
window.customElements.define('d4s-social-posts', class extends HTMLElement {
|
||||||
|
|
||||||
#basepath = 'https://api.d4science.org/rest'
|
//#basepath = 'https://api.d4science.org/rest'
|
||||||
|
#basepath = 'https://api.dev.d4science.org/rest'
|
||||||
#quantity = 20
|
#quantity = 20
|
||||||
|
#boot = null;
|
||||||
|
#data = null;
|
||||||
|
#shadowRoot = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
this.#boot = document.querySelector("d4s-boot-2")
|
||||||
|
this.#shadowRoot = this.attachShadow({mode: 'open'})
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
const shadowRoot = this.attachShadow({mode: 'open'})
|
this.fetchPosts()
|
||||||
|
}
|
||||||
|
|
||||||
var d4s = document.querySelector('d4s-boot-2')
|
fetchPosts(){
|
||||||
d4s.service(
|
const url = this.#basepath + '/2/posts/get-posts-vre'
|
||||||
this.#basepath + '/2/posts/get-posts-vre',
|
this.#boot.secureFetch(url).then(
|
||||||
'GET', null,
|
reply=>{
|
||||||
(resp) => {
|
if(reply.status !== 200) throw "Unable to fetch posts";
|
||||||
var jresp = JSON.parse(resp)
|
return reply.json()
|
||||||
if (jresp.success) {
|
}
|
||||||
|
).then(data => {
|
||||||
|
this.#data = data
|
||||||
|
this.renderPosts()
|
||||||
|
}).catch(err=>alert("Unable to fetch posts " + err))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPosts(){
|
||||||
var ul = document.createElement('ul')
|
var ul = document.createElement('ul')
|
||||||
jresp.result.reverse().forEach(post => {
|
this.#data.result.reverse().forEach(post => {
|
||||||
if (this.#quantity-- > 0) {
|
if (this.#quantity-- > 0) {
|
||||||
var li = document.createElement('li')
|
var li = document.createElement('li')
|
||||||
li.setAttribute('class', 'd4s-social-post')
|
li.setAttribute('class', 'd4s-social-post')
|
||||||
const datetime = new Date(0)
|
const datetime = new Date(0)
|
||||||
datetime.setUTCMilliseconds(post.time)
|
datetime.setUTCMilliseconds(post.time)
|
||||||
const thumbnail = (!post.thumbnail_url.startsWith('http')) ? 'https://' + d4s.clientId + post.thumbnail_url : post.thumbnail_url
|
const thumbnail = (!post.thumbnail_url.startsWith('http')) ? 'https://' + this.#boot.clientId + post.thumbnail_url : post.thumbnail_url
|
||||||
li.innerHTML = `
|
li.innerHTML = `
|
||||||
<div class="d4s-post-heading">
|
<div class="d4s-post-heading">
|
||||||
<div class="d4s-post-avatar">
|
<div class="d4s-post-avatar">
|
||||||
|
@ -44,11 +59,7 @@ window.customElements.define('d4s-social-posts', class extends HTMLElement {
|
||||||
ul.appendChild(li)
|
ul.appendChild(li)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
shadowRoot.appendChild(ul)
|
this.#shadowRoot.appendChild(ul)
|
||||||
}
|
|
||||||
},
|
|
||||||
() => { alert('Forbidden') }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get observedAttributes() {
|
static get observedAttributes() {
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
*/
|
*/
|
||||||
class D4SStorageHtmlElement extends HTMLElement {
|
class D4SStorageHtmlElement extends HTMLElement {
|
||||||
|
|
||||||
#d4s = null
|
|
||||||
#d4smissmsg = 'Required d4s-boot-2 component not found'
|
|
||||||
|
|
||||||
#baseurl = 'https://api.d4science.org/workspace'
|
#d4smissmsg = 'Required d4s-boot-2 component not found'
|
||||||
//#baseurl = 'https://storagehub.pre.d4science.net/storagehub/workspace'
|
//#baseurl = 'https://api.d4science.org/workspace'
|
||||||
|
#baseurl = 'https://workspace-repository.dev.d4science.org/storagehub/workspace'
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
@ -20,16 +19,6 @@ class D4SStorageHtmlElement extends HTMLElement {
|
||||||
root.appendChild(linkElem1)
|
root.appendChild(linkElem1)
|
||||||
}
|
}
|
||||||
|
|
||||||
get d4s() {
|
|
||||||
if (this.#d4s == null) {
|
|
||||||
this.#d4s = document.querySelector('d4s-boot-2')
|
|
||||||
if (!this.#d4s) {
|
|
||||||
console.error(this.#d4smissmsg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.#d4s
|
|
||||||
}
|
|
||||||
|
|
||||||
buildListUrl(id) {
|
buildListUrl(id) {
|
||||||
return this.#baseurl + '/items/' + id + '/children'
|
return this.#baseurl + '/items/' + id + '/children'
|
||||||
}
|
}
|
||||||
|
@ -58,9 +47,13 @@ window.customElements.define('d4s-storage-tree', class extends D4SStorageHtmlEle
|
||||||
#loadedClass = 'loaded'
|
#loadedClass = 'loaded'
|
||||||
#selectedClass = 'selected'
|
#selectedClass = 'selected'
|
||||||
#selectedbgcolor = 'lightgray'
|
#selectedbgcolor = 'lightgray'
|
||||||
|
#shadowRoot
|
||||||
|
#boot = null
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
|
this.#boot = document.querySelector('d4s-boot-2')
|
||||||
|
this.#shadowRoot = this.attachShadow({mode: 'open'})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -75,8 +68,7 @@ window.customElements.define('d4s-storage-tree', class extends D4SStorageHtmlEle
|
||||||
download of a file (domenica.jpg): https://storagehub.pre.d4science.net/storagehub/workspace/items/a5086811-59d1-4230-99fa-98431e820cf1/download
|
download of a file (domenica.jpg): https://storagehub.pre.d4science.net/storagehub/workspace/items/a5086811-59d1-4230-99fa-98431e820cf1/download
|
||||||
*/
|
*/
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
const shadowRoot = this.attachShadow({mode: 'open'})
|
this.appendStylesheets(this.#shadowRoot)
|
||||||
this.appendStylesheets(shadowRoot)
|
|
||||||
|
|
||||||
var div = document.createElement('div')
|
var div = document.createElement('div')
|
||||||
const style = `
|
const style = `
|
||||||
|
@ -94,22 +86,22 @@ window.customElements.define('d4s-storage-tree', class extends D4SStorageHtmlEle
|
||||||
`
|
`
|
||||||
div.innerHTML = style
|
div.innerHTML = style
|
||||||
|
|
||||||
this.d4s.service(
|
|
||||||
this.baseUrl + '/vrefolder',
|
this.#boot.secureFetch(this.baseUrl + '/vrefolder').then(
|
||||||
'GET', null,
|
(reply)=>{
|
||||||
(resp) => {
|
if(reply.status !== 200) throw "Unable to load folder";
|
||||||
this.parseResponse(div, resp)
|
return reply.json()
|
||||||
shadowRoot.appendChild(div)
|
}
|
||||||
},
|
).then(data => {
|
||||||
(err) => { alert(err) }
|
this.parseResponse(div, data)
|
||||||
)
|
this.#shadowRoot.appendChild(div)
|
||||||
|
}).catch(err=>alert(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
parseResponse(parentElement, response) {
|
parseResponse(parentElement, jresp) {
|
||||||
parentElement.classList.add(this.#loadedClass)
|
parentElement.classList.add(this.#loadedClass)
|
||||||
var ul = document.createElement('ul')
|
var ul = document.createElement('ul')
|
||||||
ul.classList.add('nested')
|
ul.classList.add('nested')
|
||||||
var jresp = JSON.parse(response)
|
|
||||||
if (jresp.item) {
|
if (jresp.item) {
|
||||||
const itemname = jresp.item.displayName
|
const itemname = jresp.item.displayName
|
||||||
const itemid = jresp.item.id
|
const itemid = jresp.item.id
|
||||||
|
@ -172,12 +164,12 @@ window.customElements.define('d4s-storage-tree', class extends D4SStorageHtmlEle
|
||||||
if (li.classList.contains(this.#loadedClass)) {
|
if (li.classList.contains(this.#loadedClass)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.d4s.service(
|
this.#boot.secureFetch(this.buildListUrl(id)).then(reply=>{
|
||||||
this.buildListUrl(id),
|
if(reply.status !== 200) throw "Unable to load folder";
|
||||||
'GET', null,
|
return reply.json()
|
||||||
(resp) => this.parseResponse(li, resp),
|
}).then(data=>{
|
||||||
(err) => { alert(err) }
|
this.parseResponse(li, data)
|
||||||
)
|
}).catch(err=>alert(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
displayPath(li) {
|
displayPath(li) {
|
||||||
|
@ -315,7 +307,7 @@ window.customElements.define('d4s-storage-folder', class extends D4SStorageHtmlE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.info("Download of " + item.id)
|
console.info("Download of " + item.id)
|
||||||
this.d4s.download(this.buildDownloadUrl(item.id), item.name)
|
this.#boot.download(this.buildDownloadUrl(item.id), item.name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue