init console admin

develop
Morisse 6 years ago
commit 94ab7162e9
  1. 21
      .gitignore
  2. 161
      docs/TODO
  3. 11413
      package-lock.json
  4. 20
      package.json
  5. BIN
      public/favicon.ico
  6. 45
      public/index.html
  7. 15
      public/manifest.json
  8. 28
      src/App.css
  9. 53
      src/App.js
  10. 9
      src/App.test.js
  11. 5
      src/index.css
  12. 8
      src/index.js
  13. 7
      src/logo.svg
  14. 117
      src/registerServiceWorker.js

21
.gitignore vendored

@ -0,0 +1,21 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,161 @@
User Admin:
Only users that are server admins can use these APIs. A user can be marked as a server admin by updating the database directly, e.g.:
UPDATE users SET admin = 1 WHERE name = '@foo:bar.com'
Create user:
Remove/deactivate user:
should we be able to hard remove (GDPR)
Deactivate Account:
This API deactivates an account. It removes active access tokens, resets the password, and deletes third-party IDs (to prevent the user requesting a password reset).
The api is:
POST /_matrix/client/r0/admin/deactivate/<user_id>
including an access_token of a server admin, and an empty request body.
Destroy room:
remove all users and block access or remove all trace of room in db?
Deactivate room:
can it be reactivated?
Reset password:
Changes the password of another user.
The api is:
POST /_matrix/client/r0/admin/reset_password/<user_id>
with a body of:
{
"new_password": "<secret>"
}
including an access_token of a server admin.
Display rooms list:
Show users list:
statistics: facturation, number of messages, check by users access to active session, device, location
Hello,
pour l'interface de paramétrage / suivi pour nos intégrateurs, j'ai identifié les phases de vie / actions / infos. Pourriez-vous svp me dire si c'est complet ? dès que nous sommes alignés je fais une proposition d'IHM si ça vous va:
1/ Installation :
Nom de l’entreprise
Noms prénoms mails des participants
2/ Maintien :
Etat du serveur ok / ok
Nombre de rooms
Mémoire utilisée
Listes des users et invités
Accès aux logs ? lesquels ?
Ajouter des participants
Nom prénom mail
Supprimer des participants
Pick from list
Next step : archivage des rooms
1/ Installation :
Nom de l’entreprise
Noms prénoms mails des participants
2/ Maintien :
Etat du serveur ok / ok
Nombre de rooms
Mémoire utilisée
Listes des users et invités
Accès aux logs ? lesquels ?
Ajouter des participants
Nom prénom mail
Supprimer des participants
Pick from list
Next step : archivage des rooms
1/ Installation :
Nom de l’entreprise
Noms prénoms mails des participants
2/ Maintien :
Etat du serveur ok / ok
Nombre de rooms
Mémoire utilisée
Listes des users et invités
Accès aux logs ? lesquels ?
Ajouter des participants
Nom prénom mail
Supprimer des participants
Pick from list
Next step : archivage des rooms
Alexandre Storelli
Je verrais aussi nom du sous-domaine voulu
Du genre Bernard et Dugenou Avocats pourraient vouloir avoir bdavocats.watcha.fr
Autre item pour installation: serveur mail interne ou sendinblue
Maintien: changer l'admin
Distinction entre supprimer participant (bloquer son compte) et supprimer participant (supprimer compte et messages)
Xavier
thx Alex, je pensais que l'on figeait automatiquement le nom de domaine en faisant nomentreprise.domaineintégrateur.xx (ce peut être le nom de domaine de l'intégrateur)
merci pour les autres remarques
Alexandre Storelli
un nom d'entreprise n'est pas unique, il y a un risque de collisions. Par exemple watcha https://www.societe.com/cgi-bin/search?champs=watcha
sinon OK bien sûr pour le sous-domaine chez l'intégrateur
Xavier
Tu as raison!
pour nos intégrateurs: quel sera selon vous le serveur mail? ils utilisent le notre? on leur en déploie un?
dez je crois qu'on en avait déjà parlé
Alexandre Storelli
Et t'as des noms d'entreprises très longs, du genre https://www.societe.com/societe/picardie-maritime-habitat-fondation-paul-duclercq-005720610.html du coup il faut pouvoir choisir la façon de l'abréger
Pour les serveurs mail, on peut proposer le nôtre par défaut, et donner une option à l'intégrateur pour mettre celui qu'il souhaite (champs SMTP, port, login, mdp, protocole...)
Ce n'est pas à nous d'en déployer un à mon sens, mais c'est un truc qu'ils maîtrisent bien
Xavier
c'est pas des emmerdes en plus pour nous? (certificats, etc...) pas plus simple d'imposer le notre?
Alexandre Storelli
Ça ne me semble pas poser de souci particulier. Au contraire, vu que c'est délicat d'envoyer un mail qui n'arrive pas dans les spams depuis un canon à mail, les serveurs déjà existants des boîtes clientes feront un meilleur travail
De plus, c'est un gros argument de confidentialité pour les clients
Car on ne peut pas être sûr qu'il n'y a pas de petits malins chez SendInBlue qui lisent nos emails
Alors que sur le serveur mail de Résophone, il y a des types de résophone qui veillent au grain et ça devient leur problème, plus le nôtre
François G
+1
Xavier
c'est beau cet alignement des astres ;-)
merci à vous
Alexandre Storelli
J'ajouterais aussi un état des lieux sur la facturation, en lien avec une liste donnée de salons (si ça a lieu d'être)
Xavier
oui tu as raison: je mentionne Nombre de rooms et Mémoire utilisée mais il faut aussi le forfait en cours
Alexandre Storelli
Ah oui pardon je n'avais pas lu assez attentivement
Xavier
non non c'est très bien ça me fait penser à ajouter le forfait en cours
Alexandre Storelli
ok :)
Pour les logs, c'est dur à dire. Fournir l'intégralité des logs de nos différentes briques est un peu violent. Mais donner cet accès peut aussi être un gage de transparence et leur sous-entendre que c'est aussi à eux de les serveiller.
*surveiller
Sylvain
Cool le fix de setup account alex ca marche nickel
Alexandre Storelli
Super!
J'ai pas mal avancé sur la page du site pour les apps mobiles
Sylvain
good
Alexandre Storelli
Pour les logs, après réflexion, je suis favorable à donner l'intégralité des accès à l'intégrateur. Présenté sous forme d'onglets selon chaque thématique (serveur, conf, système...). Ça facilitera la communication entre l'intégrateur et nous s'il faut faire du debug ou analyser des attaques. François G & Sylvain quelle est votre position sur la question?

11413
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
{
"name": "console_admin",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-scripts": "1.1.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"bootstrap": "^4.1.3",
"react-bootstrap": "^0.32.3"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -0,0 +1,45 @@
<!DOCTYPE html>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

@ -0,0 +1,15 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

@ -0,0 +1,28 @@
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}
.App-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}
.App-title {
font-size: 1.5em;
}
.App-intro {
font-size: large;
}
@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

@ -0,0 +1,53 @@
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import {Bootstrap, Grid, Row, Col, Button,FormGroup,ControlLabel,FormControl,HelpBlock} from 'react-bootstrap';
class App extends Component {
constructor(props, context) {
super(props, context);
this.handleChange = this.handleChange.bind(this);
this.state = {
value: ''
};
}
getValidationState() {
const length = this.state.value.length;
if (length > 10) return 'success';
else if (length > 5) return 'warning';
else if (length > 0) return 'error';
return null;
}
handleChange(e) {
this.setState({ value: e.target.value });
}
render() {
return (
<form>
<FormGroup
controlId="formBasicText"
validationState={this.getValidationState()}
>
<ControlLabel>Working example with validation</ControlLabel>
<FormControl
type="text"
value={this.state.value}
placeholder="Enter text"
onChange={this.handleChange}
/>
<FormControl.Feedback />
<HelpBlock>Validation is based on string length.</HelpBlock>
</FormGroup>
</form>
);
}
}
export default App;

@ -0,0 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});

@ -0,0 +1,5 @@
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}

@ -0,0 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,117 @@
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://goo.gl/SC7cgQ'
);
});
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl);
}
});
}
}
function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}
Loading…
Cancel
Save