Merge branch 'release/auto-registration'

This commit is contained in:
Jean-Baptiste Pasquier 2021-02-22 09:51:45 +01:00
commit 5cc3e9b7f4
21 changed files with 381 additions and 120 deletions

View File

@ -110,6 +110,7 @@ On `config.json`:
"authority": "http://localhost:8000/",
"endpoints": {
"get": {
"communities": "http://server.url/open-communities/",
"skills": "http://server.url/skills/",
"users": "http://server.url/users/"
},
@ -126,6 +127,7 @@ Where:
* `clientLogo` is an URL to an image file
* `xmppWebsocket` is your [Prosody](https://prosody.im/) with [appropriate modules](https://git.startinblox.com/infra/prosody-modules/) configured on.
* `authority` is the OpenID Provider. Usually, if you use `djangoldp-account` it's the same as your djangoldp server.
* `endpoints.*.communities` is the API endpoints for Open Communities on your djangoldp server. (djangoldp-community)
* `endpoints.*.users` is the API endpoints for Users on your djangoldp server. (djangoldp-account)
* `endpoints.*.skills` is the API endpoints for Skills on your djangoldp server. (djangoldp-skill)
* `endpoints.*.uploads` is the API endpoints for Uploads on your djangoldp server. (djangoldp-upload)
@ -140,6 +142,8 @@ Communities are mandatory to have an Hubl. If you're upgrading an existion Hubl,
Don't forget to set some users as admin from the Django Admin if you want to allow them to create new users from app.
If you set `allow_self_registration` on your community, it'll disable the auto-login feature of Hubl and allow your users to self register on your application.
### Optional personalisation
On `config.json`:

View File

@ -5,10 +5,12 @@
"authority": "http://localhost:8000/",
"endpoints": {
"get": {
"communities": "http://localhost:8000/open-communities/",
"skills": "http://localhost:8000/skills/",
"users": "http://localhost:8000/users/"
},
"post": {
"communities": "http://localhost:8000/communities/",
"users": "http://localhost:8000/users/",
"upload": "http://localhost:8000/upload/"
}

6
package-lock.json generated
View File

@ -1159,9 +1159,9 @@
}
},
"@startinblox/hubl-styling-framework": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/@startinblox/hubl-styling-framework/-/hubl-styling-framework-1.8.6.tgz",
"integrity": "sha512-2SWeVC3bd6jkc+cwgV1vh359ntYqAaWWqgDBCvfadgSCxVIdrNf6tuEdI2H9jpIBDDJXikKt9E20qCL13WxtKQ=="
"version": "1.8.8",
"resolved": "https://registry.npmjs.org/@startinblox/hubl-styling-framework/-/hubl-styling-framework-1.8.8.tgz",
"integrity": "sha512-SKVRUV95f45qIGSgpIMvgbQaZ6mPNNCXQY+6LlU18lGMvq0vwQ3AmOuTkp4VbfUWvSLYXTUE1N61YmIFikMIfw=="
},
"@types/q": {
"version": "1.5.4",

View File

@ -45,7 +45,7 @@
]
},
"dependencies": {
"@startinblox/hubl-styling-framework": "^1.8.6",
"@startinblox/hubl-styling-framework": "^1.8.8",
"cross-env": "^7.0.3",
"fs-extra": "^9.0.1",
"normalize.css": "^8.0.1",

View File

@ -0,0 +1,20 @@
import { Sib } from 'https://cdn.skypack.dev/@startinblox/core@0.15';
export const HublAutoLogin = {
name: 'hubl-auto-login',
created() {
document
.querySelectorAll(".loggedIn-loader")
.forEach(el => (el.style.display = "flex"));
window.dispatchEvent(
new CustomEvent('requestNavigation', {
detail: {
route: "dashboard"
}
}),
);
document.querySelector("sib-auth").login();
}
}
Sib.register(HublAutoLogin);

View File

@ -37,7 +37,7 @@ if endpoints.get
//- script(type="module" src="/lib/solid-dashboard/dist/index.js" defer)
if endpoints.get.users
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-chat@4.0" defer)
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-chat@4.1" defer)
//- script(type="module" src="/lib/solid-xmpp-chat/dist/index.js" defer)
//- Disabled - Not in core@0.15

View File

@ -26,6 +26,7 @@ html(lang="en")
script(src="https://browser.sentry-cdn.com/5.25.0/bundle.tracing.min.js" defer)
script(type="module" src="/components/sentry.js" defer)
script(type="module" src="/components/hubl-auto-login.js" defer)
script(type="module" src="/components/hubl-search-users.js" defer)
script(type="module" src="/components/hubl-status.js" defer)
script(type="module" src="/components/hubl-reactivity.js" defer)
@ -41,7 +42,7 @@ html(lang="en")
body.bg-color-grey
if endpoints.get && endpoints.post
.notLoggedIn(style='visibility:hidden;')
sib-auth(style='display:none!important', auto-login)
sib-auth(style='display:none!important')
sib-auth-provider(
data-authority=`${authority}`
data-id=`${authorityName || "authority"}`
@ -77,9 +78,9 @@ html(lang="en")
hubl-reactivity(data-src=`${endpoints.post.projects}` target-src=`${endpoints.get.projects}`)
hubl-reactivity(bind-user nested-field="projects" target-src=`${endpoints.post.projects}`)
hubl-reactivity(bind-user nested-field="projects" target-src=`${endpoints.post.projects}joinable/`)
hubl-reactivity(data-src=`${endpoints.projects || endpoints.get.projects}joinable/` target-src=`${endpoints.projects || endpoints.get.projects}`)
hubl-reactivity(bind-user nested-field="projects" target-src=`${endpoints.projects || endpoints.get.projects}`)
hubl-reactivity(bind-user nested-field="projects" target-src=`${endpoints.projects || endpoints.get.projects}joinable/`)
hubl-reactivity(data-src=`${endpoints.get.projects}joinable/` target-src=`${endpoints.get.projects}`)
hubl-reactivity(bind-user nested-field="projects" target-src=`${endpoints.get.projects}`)
hubl-reactivity(bind-user nested-field="projects" target-src=`${endpoints.get.projects}joinable/`)
include views/page-project.pug
if endpoints.get.circles
@ -90,9 +91,9 @@ html(lang="en")
hubl-reactivity(data-src=`${endpoints.post.circles}` target-src=`${endpoints.get.circles}`)
hubl-reactivity(bind-user nested-field="circles" target-src=`${endpoints.post.circles}`)
hubl-reactivity(bind-user nested-field="circles" target-src=`${endpoints.post.circles}joinable/`)
hubl-reactivity(data-src=`${endpoints.circles || endpoints.get.circles}joinable/` target-src=`${endpoints.circles || endpoints.get.circles}`)
hubl-reactivity(bind-user nested-field="circles" target-src=`${endpoints.circles || endpoints.get.circles}`)
hubl-reactivity(bind-user nested-field="circles" target-src=`${endpoints.circles || endpoints.get.circles}joinable/`)
hubl-reactivity(data-src=`${endpoints.get.circles}joinable/` target-src=`${endpoints.get.circles}`)
hubl-reactivity(bind-user nested-field="circles" target-src=`${endpoints.get.circles}`)
hubl-reactivity(bind-user nested-field="circles" target-src=`${endpoints.get.circles}joinable/`)
include views/page-circle.pug
if endpoints.get.users
@ -127,20 +128,134 @@ html(lang="en")
hubl-reactivity(data-src=`${endpoints.post.joboffers}current/` target-src=`${endpoints.get.joboffers}`)
hubl-reactivity(data-src=`${endpoints.post.joboffers}expired/` target-src=`${endpoints.get.joboffers}`)
hubl-reactivity(data-src=`${endpoints.post.joboffers}` target-src=`${endpoints.get.joboffers}`)
hubl-reactivity(data-src=`${endpoints.joboffers || endpoints.get.joboffers}current/` target-src=`${endpoints.joboffers || endpoints.get.joboffers}`)
hubl-reactivity(data-src=`${endpoints.joboffers || endpoints.get.joboffers}current/` target-src=`${endpoints.joboffers || endpoints.get.joboffers}expired/`)
hubl-reactivity(data-src=`${endpoints.joboffers || endpoints.get.joboffers}expired/` target-src=`${endpoints.joboffers || endpoints.get.joboffers}`)
hubl-reactivity(bind-user nested-field="joboffers" target-src=`${endpoints.joboffers || endpoints.get.joboffers}expired/`)
hubl-reactivity(bind-user nested-field="joboffers" target-src=`${endpoints.joboffers || endpoints.get.joboffers}`)
hubl-reactivity(bind-user nested-field="joboffers" target-src=`${endpoints.joboffers || endpoints.get.joboffers}current/`)
hubl-reactivity(data-src=`${endpoints.get.joboffers}current/` target-src=`${endpoints.get.joboffers}`)
hubl-reactivity(data-src=`${endpoints.get.joboffers}current/` target-src=`${endpoints.get.joboffers}expired/`)
hubl-reactivity(data-src=`${endpoints.get.joboffers}expired/` target-src=`${endpoints.get.joboffers}`)
hubl-reactivity(bind-user nested-field="joboffers" target-src=`${endpoints.get.joboffers}expired/`)
hubl-reactivity(bind-user nested-field="joboffers" target-src=`${endpoints.get.joboffers}`)
hubl-reactivity(bind-user nested-field="joboffers" target-src=`${endpoints.get.joboffers}current/`)
include views/page-job-offers.pug
.loggedIn(style='position:absolute;top:calc(50% - 10px);left:calc(50% - 40px);')
#login(data-view="login", hidden).segment.full.bg-color-secondary.text-center.index-community.loggedIn
.segment.half.sm-full.bg-color-white.text-center
.segment.half.sm-full
div.community-logo
img(src=clientLogo style='max-width:100%;max-height:100%;')
p.text-xlarge.text-semibold.margin-top-xxlarge.line-xlarge(data-trans="communities.index.youKnow")
button.segment.full.sm-three-quarter.button.text-xsmall.text-bold.text-uppercase.color-secondary.bordered.padding-bottom.xlarge.padding-top.xlarge.community-button#loginButton(
data-trans="communities.index.login"
)
p.text-xlarge.text-semibold.margin-top-xxlarge.line-xlarge(data-trans="communities.index.newUser")
solid-widget(name='hubl-index-community-logo')
template ${value != "" ? `<div class="community-button-flexed"><img src="${value}" style="max-width:100%;max-height:80px" class="padding-xsmall" /></div>` : ""}
solid-widget(name='hubl-index-community-text')
template
.community-button-flexed-large.whitespace-normal
span(data-trans="communities.index.createAccount")
span &nbsp;
span ${value}
solid-widget(name='hubl-index-select-community')
template
solid-link.segment.full.sm-three-quarter.button.text-xsmall.text-bold.text-uppercase.color-secondary.bordered.padding-bottom.xlarge.padding-top.xlarge.margin-top-xsmall.community-button.community-button-flex-container(
next='join-community'
data-src='${src}'
)
solid-display(
data-src='${src}'
fields='logo, name'
widget-logo='hubl-index-community-logo'
widget-name='hubl-index-community-text'
)
if endpoints.get.communities
div.loader#hubl-index-community-selector-loader
div
div
div
div
solid-display.community-flex-container(
data-src=`${endpoints.get.communities}`
fields='action'
action-action='action'
widget-action='hubl-index-select-community'
loader-id='hubl-index-community-selector-loader'
order-asc='name'
empty-widget='hubl-auto-login'
id='hubl-index-community-selector'
)
#join-community(data-view="join-community", hidden, no-render).segment.full.bg-color-secondary.text-center.index-community.loggedIn
.segment.half.sm-full.bg-color-white.text-center
.segment.half.sm-full
solid-widget(name="hubl-index-community-join-logo")
template
img(src="${value}" style="max-width:100%;max-height:100%;")
solid-display(
bind-resources
fields="logo"
widget-logo="hubl-index-community-join-logo"
class-logo='community-logo'
default-logo=clientLogo
)
solid-widget(name='hubl-input-type-password')
template
label ${label}
input(
type="password"
name="user.password"
required
data-holder
)
solid-widget(name='hubl-input-type-email')
template
label ${label}
input(
type="email"
name="user.email"
required
data-holder
)
solid-form.segment.full.padding-top-xlarge.padding-very-xxlarge.sm-padding-xsmall.sm-padding-top-medium.whitespace-normal.form(
bind-resources
nested-field='members'
fields='user.first_name, user.last_name, user.email, user.username, user.password'
label-user.first_name='Prénom*'
label-user.last_name='Nom*'
label-user.email='E-mail*'
label-user.password='Mot de passe*'
data-trans='label-user.password=communities.index.password;label-user.email=communities.index.email;label-user.last_name=communities.index.last_name;label-user.first_name=communities.index.first_name;submit-button=communities.index.formCreateAccount'
widget-user.first_name='solid-form-text-label'
widget-user.last_name='solid-form-text-label'
widget-user.email='hubl-input-type-email'
widget-user.password='hubl-input-type-password'
widget-user.username='solid-form-hidden'
class-user.first_name='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left'
class-user.last_name='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left'
class-user.email='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left'
class-user.password='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left'
required-user.first_name
required-user.last_name
required-user.email
required-user.password
pattern-user.first_name='.+'
pattern-user.last_name='.+'
value-user.username='generate-an-username'
submit-button=''
id='user-creation-form'
next='dashboard'
)
.loggedIn-loader.bg-color-grey(style='position:fixed;width:100%;height:100%;;z-index:999999;top:0;left:0;display:flex;align-items:center;justify-content:center;')
div
div.loader
div
div
div
div
div#something-goes-wrong(hidden)
br
span(data-trans="errors.somethingGoesWrong")
span &nbsp;
a(data-trans='errors.reload' href='/')
div(
id="swal-content-text"

View File

@ -128,7 +128,18 @@
"subTitle": "Communities",
"tableHeader1": "Name",
"tableHeader2": "Action",
"searchBy": "Find a community by name"
"searchBy": "Find a community by name",
"index": {
"youKnow": "Do you know the place?",
"newUser": "Are you new around here?",
"createAccount": "Create an account on",
"login": "Connect to my account",
"first_name": "First name*",
"last_name": "Last name*",
"email": "Email*",
"password": "Password*",
"formCreateAccount": "Create an account"
}
},
"project": {
"menuRight": {
@ -224,5 +235,9 @@
"private": "Private",
"public": "Public"
},
"success": "Success!"
"success": "Success!",
"errors": {
"somethingGoesWrong": "Something goes wrong, try to",
"reload": "reload"
}
}

View File

@ -128,7 +128,18 @@
"subTitle": "Comunidades",
"tableHeader1": "Nombre",
"tableHeader2": "Acción",
"searchBy": "Encuentra una comunidad por nombre "
"searchBy": "Encuentra una comunidad por nombre ",
"index": {
"youKnow": "¿Conoce el lugar?",
"newUser": "¿Eres nuevo por aquí?",
"createAccount": "Crea una cuenta en",
"login": "Conectar a mi cuenta",
"first_name": "Nombre*",
"last_name": "Apellido*",
"email": "Correo electrónico*",
"password": "Contraseña*",
"formCreateAccount": "Crear una cuenta"
}
},
"project": {
"menuRight": {
@ -224,5 +235,9 @@
"private": "Privado",
"public": "Público"
},
"success": "¡Éxito!"
"success": "¡Éxito!",
"errors": {
"somethingGoesWrong": "Algo sale mal, intenta",
"reload": "recargar"
}
}

View File

@ -129,7 +129,18 @@
"subTitle": "Communautés",
"tableHeader1": "Nom",
"tableHeader2": "Action",
"searchBy": "Rechercher une communauté par nom"
"searchBy": "Rechercher une communauté par nom",
"index": {
"youKnow": "Tu connais la maison ?",
"newUser": "Tu es nouveau par ici ?",
"createAccount": "Créer un compte sur",
"login": "Se connecter à mon compte",
"first_name": "Prénom*",
"last_name": "Nom*",
"email": "E-mail*",
"password": "Mot de passe*",
"formCreateAccount": "Créer un compte"
}
},
"project": {
"menuRight": {
@ -225,5 +236,9 @@
"private": "Privé",
"public": "Public"
},
"success": "Succès!"
"success": "Succès!",
"errors": {
"somethingGoesWrong": "Quelque chose ne va pas, essayez de",
"reload": "recharger"
}
}

View File

@ -1,3 +1,4 @@
window.requestLogin = false;
document.addEventListener("DOMContentLoaded", function () {
document
.querySelector("sib-auth")
@ -10,6 +11,45 @@ document.addEventListener("DOMContentLoaded", function () {
document
.querySelectorAll(".loggedIn")
.forEach(el => (el.style.display = "none"));
document
.querySelectorAll(".loggedIn-loader")
.forEach(el => (el.style.display = "none"));
} else {
window.requestLogin = true;
window.dispatchEvent(
new CustomEvent('requestNavigation', {
detail: {
route: "login",
wanted: true
}
}),
);
document
.querySelectorAll(".loggedIn-loader")
.forEach(el => (el.style.display = "none"));
}
});
});
window.addEventListener("navigate", e => {
if (e.detail.route == "login" && !window.requestLogin) {
window.dispatchEvent(
new CustomEvent('requestNavigation', {
detail: {
route: "dashboard"
}
}),
);
}
});
document.querySelector('#loginButton').addEventListener('click', () => {
document
.querySelectorAll(".loggedIn")
.forEach(el => (el.style.display = "none"));
document
.querySelectorAll(".loggedIn-loader")
.forEach(el => (el.style.display = "flex"));
setTimeout(() => {
document.querySelector('#something-goes-wrong').removeAttribute('hidden');
}, 5000);
document.querySelector('sib-auth').login();
});

View File

@ -69,6 +69,22 @@ document.addEventListener("DOMContentLoaded", function() {
}
closeLeftMenu();
closeUserControls();
if(e.detail.route.startsWith('login')) {
document
.querySelector("sib-auth")
.getUser()
.then(user => {
if (user !== null) {
window.dispatchEvent(
new CustomEvent('requestNavigation', {
detail: {
route: "dashboard"
}
}),
);
}
});
}
});
// Document -> close menu
document.addEventListener("click", event => {

View File

@ -0,0 +1,5 @@
setTimeout(() => {
if(document.querySelector('.loggedIn-loader').style.display != 'none') {
document.querySelector('#something-goes-wrong').removeAttribute('hidden')
}
}, 10000);

View File

@ -0,0 +1,7 @@
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#user-creation-form').addEventListener('save', event => {
if(event.originalTarget.id == 'user-creation-form') {
document.querySelector("sib-auth").login();
}
});
});

View File

@ -1,68 +0,0 @@
function applyAdapt(prefix, sibDisplay, user) {
//- Allow to bind-user on selected attribute
if (sibDisplay.getAttribute(prefix + "-user-id")) {
sibDisplay.setAttribute(
sibDisplay.getAttribute(prefix + "-user-id"),
user["@id"]
);
}
//- Allow to set data-src to a children solid-form
if (sibDisplay.getAttribute(prefix + "-bind-resources")) {
let form = sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-resources") + " solid-form"
);
if (form) {
form.setAttribute(
"data-src",
sibDisplay.component.resourceId.replace("members/", "")
);
}
}
//- Allow to put user on a targetted search field
if (sibDisplay.getAttribute(prefix + "-bind-user2input")) {
let qS = sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-user2input")
);
if(qS) qS.value = user["@id"];
}
}
//- This function is a workaround for the currently unworking populate
//- Feel free to see examples on page-circles-
function recursiveAdaptWidgets(prefix, element, user) {
element.addEventListener("populate", () => {
element.querySelectorAll("[" + prefix + "-user-id]").forEach(el => {
el.setAttribute(el.getAttribute(prefix + "-user-id"), user["@id"]);
});
applyAdapt(prefix, element, user);
document.querySelectorAll('solid-display, solid-form').forEach(sibDisplay => {
applyAdapt(prefix, sibDisplay, user);
});
});
}
document.addEventListener("DOMContentLoaded", function () {
document
.querySelector("sib-auth")
.getUser()
.then(user => {
if (user !== null) {
document.querySelectorAll('solid-display, solid-form').forEach(element => {
// Set current user id on set-user-id of solid-display
recursiveAdaptWidgets("hubl-inherit", element, user);
});
for (leaveBtn of document.querySelectorAll(
"admin-circle-leave > solid-ac-checker:not([hidden])"
)) {
// Hide Join button
leaveBtn.parentNode.parentNode.parentNode.nextElementSibling.setAttribute(
"style",
"display:none !important"
);
}
}
});
});

View File

@ -0,0 +1,82 @@
.index-community {
position: absolute;
top: 0;
left: 0;
height: 100%;
>div {
min-height: 75%;
margin-top: 100px;
padding-bottom: 70px;
@media (max-width: 768px) {
margin: 0;
min-height: 100%;
}
.community-logo {
max-width: 100%;
height: 100px;
margin-top: 70px;
display: flex;
align-items: center;
justify-content: center;
}
.community-button {
height: 80px;
border-radius: 5px;
}
.community-button-flexed {
flex-basis: 33%;
flex-grow: 1;
flex-shrink: 1;
}
.community-button-flexed-large {
flex-basis: 66%;
flex-grow: 1;
flex-shrink: 1;
}
.community-flex-container {
display: flex;
flex-wrap: wrap;
text-align: center;
justify-content: center;
>div>solid-display {
display: contents;
>div>hubl-index-select-community {
display: contents;
}
}
}
.community-button-flex-container {
display: flex;
align-items: center;
justify-content: center;
>solid-display,
hubl-index-community-logo,
hubl-index-community-text {
display: contents;
}
}
}
solid-form-text-label,
hubl-input-type-password,
hubl-input-type-email {
color: #5D7393;
}
label {
text-align: left;
}
input[type="submit"] {
float: initial !important;
}
}

View File

@ -42,6 +42,7 @@ solid-display>div {
@import 'job-offers';
@import 'chat';
@import 'forms';
@import 'communities';
nav#main__menu {
@media (min-width: 768.01px) {

View File

@ -80,9 +80,8 @@ solid-router(default-route='circle-profile', hidden)
widget-relation='hubl-circle-leave-button'
search-fields='user'
search-widget-user='solid-form-hidden'
search-value-user=""
search-value-user="store://user.@id"
empty-widget='hubl-circle-join-button'
hubl-inherit-user-id="search-value-user"
)
solid-ac-checker.segment.margin-left-small(permission='acl:Delete', bind-resources)
solid-delete(

View File

@ -65,13 +65,6 @@ div
button.segment.lg-hidden.icon-menu#toggleMainMenu
sib-auth(style='display:none!important', auto-login)
sib-auth-provider(
data-authority=`${authority}`
data-id=`${authorityName || "authority"}`
data-client-name=`${clientName || "Hubl"}`
)
//- User menu visible on small screens
details.user-menu.segment.lg-hidden.user-controls
summary

View File

@ -228,3 +228,5 @@ solid-router#navbar-router(default-route='dashboard')
solid-route.menu(name='profile', hidden)
solid-route(name='about', hidden)
solid-route(name='join-community', use-id, hidden)
solid-route(name='login', hidden)

View File

@ -80,9 +80,7 @@ solid-router(default-route='project-profile', hidden)
search-fields='user'
search-widget-user='solid-form-hidden'
search-value-user=""
hubl-inherit-user-id="search-value-user"
search-value-user="store://user.@id"
)
h3.text-color-heading.text-bold.text-letter-spacing-large(data-trans='project.profile.captain')