main
HerrHase 2 years ago
parent 36d70399a9
commit 6ae9b9fc56

@ -1,2 +1,55 @@
# simple-frontend-xmpp-riotjs
# xmpp-login-riotjs
Small Prototyp to show login to an XMPP-Server with (xmpp.js)[https://github.com/xmppjs/xmpp.js] and retrieve Contacts from Account. Frontend is written in Riotjs, this
only tested for an Connection with Websocket (wss://<domain>/xmpp-websocket). The Configuration is below.
## Configuration
### Prosody
```
modules_enabled = {
"websocket";
}
cross_domain_websocket = { "127.0.0.1:8080", "<domain>" }
consider_websocket_secure = true
```
### Nginx
```
server {
listen 80;
listen [::]:80;
server_name <domain>;
return 301 https://<domain>$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
server_name <domain>;
# logs
access_log /var/log/nginx/<domain>.access.log;
error_log /var/log/nginx/<domain>.error.log;
location /xmpp-websocket {
proxy_pass http://127.0.0.1:5280;
proxy_http_version 1.1;
proxy_set_header Connection "Upgrade";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900s;
}
}
```

@ -0,0 +1,13 @@
{
"/public/js/spritemap.js": "/public/js/spritemap.js?id=5f6ef07e17161cb70e40e792ba88e1fa",
"/public/js/script.js": "/public/js/script.js?id=934c0625608089c8b72e0a7de4e073ed",
"/public/css/styles.css": "/public/css/styles.css?id=2ccc88f544c350d3ce83a02c6d9e0a54",
"/public/css/IBMPlexMono-Bold.eot": "/public/css/IBMPlexMono-Bold.eot?id=ef1fadf711db80a00542b202ab14f7ee",
"/public/css/IBMPlexMono-Bold.ttf": "/public/css/IBMPlexMono-Bold.ttf?id=e46cace25a93f48a2ec32800717827cb",
"/public/css/IBMPlexMono-Bold.woff": "/public/css/IBMPlexMono-Bold.woff?id=8864bd7cb954c4646045e3fc0bdec90c",
"/public/css/IBMPlexMono-Bold.woff2": "/public/css/IBMPlexMono-Bold.woff2?id=c6d3f08fe7a9fecab40d748b98c87cc5",
"/public/css/IBMPlexMono.eot": "/public/css/IBMPlexMono.eot?id=d68f064d6b86ff47b38ad486a3362d82",
"/public/css/IBMPlexMono.ttf": "/public/css/IBMPlexMono.ttf?id=60d8ae961dba3289c1d2d54e0b85c9b7",
"/public/css/IBMPlexMono.woff": "/public/css/IBMPlexMono.woff?id=18a7a5a76b4176759e2e1b3e674a7f82",
"/public/css/IBMPlexMono.woff2": "/public/css/IBMPlexMono.woff2?id=428bd06c5eb0362494016994c26188b4"
}

18338
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,19 @@
{
"private": true,
"dependencies": {
"@riotjs/observable": "^4.1.1",
"@tiny-components/plain-ui": "^0.6.0",
"@tiny-components/validator": "^0.2.0",
"@xmpp-plugins/roster": "^1.2.0",
"@xmpp/client": "^0.13.1",
"riot": "^6.1.2"
},
"devDependencies": {
"@riotjs/webpack-loader": "^6.0.0",
"laravel-mix": "^6.0.43",
"laravel-mix-purgecss": "^6.0.0",
"sass": "^1.51.0",
"sass-loader": "^12.6.0",
"svg-spritemap-webpack-plugin": "^4.4.0"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Lessons Learned | Xmpp</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link href="/css/styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<header class="header">
<div class="bar">
<div class="bar__start">
<h1 class="m-top-4 m-bottom-4 h4">
Xmpp
</h1>
</div>
<div class="bar__main justify-end">
<a class="button button--small m-left-sm-3 m-bottom-0" href="https://gitea.node001.net/tiny-components/validator" rel="noopener" target="_blank">
Gitea
<svg class="m-left-3 icon fill-text" aria-hidden="true">
<use xlink:href="symbol-defs.svg#icon-gitea"></use>
</svg>
</a>
</div>
</div>
</header>
<div class="container">
<div class="grid justify-center">
<div class="col-12 col-md-6">
<xmpp-login></xmpp-login>
<xmpp-contacts></xmpp-contacts>
</div>
</div>
</div>
<script type="text/javascript" src="/js/script.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
(self.webpackChunk=self.webpackChunk||[]).push([[355],{1256:()=>{}}]);

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

@ -0,0 +1,51 @@
<xmpp-contacts>
<div class="panel m-top-6" if={ state.contacts.length > 0 }>
<div class="bar">
<div class="bar__main">
Contacts
</div>
</div>
<div class="panel__body">
<ul>
<li each={ contact in state.contacts }>
{ contact.name }
</li>
</ul>
</div>
</div>
<script>
import setupRoster from "@xmpp-plugins/roster"
import xmppStore from './../stores/xmpp.js'
export default {
state: {
contacts: []
},
onMounted() {
xmppStore.on('online', (address) => {
const roster = setupRoster(xmppStore.xmpp)
roster.get().then(roster => {
if (!roster) {
// the roster hasn't changed since last version
return
}
const { version, items } = roster
this.state.contacts = items
this.update()
})
})
xmppStore.on('offline', (address) => {
this.state.contacts = []
this.update()
})
}
}
</script>
</xmpp-contacts>

@ -0,0 +1,142 @@
<xmpp-login>
<div class="panel m-top-6">
<div class="bar">
<div class="bar__start">
Account
</div>
</div>
<div class="panel__body">
<form onsubmit={ (event) => { state.validator.submit(event) }} if={ !state.isOnline }>
<div class="field-group">
<label class="field-label">
Service
<input type="text" class="field-text" name="service" />
<field-error name="service"></field-error>
</label>
</div>
<div class="field-group">
<label class="field-label">
Username
<input type="text" class="field-text" name="username" />
<field-error name="username"></field-error>
</label>
</div>
<div class="field-group">
<label class="field-label">
Password
<input type="password" class="field-text" name="password" />
<field-error name="password"></field-error>
</label>
</div>
<div class="loading" if={ state.isLoading }>
<span></span>
<span></span>
<span></span>
</div>
<div class="m-top-4">
<button class="button button--full button--success center w-100" disabled={ state.isLoading } type="submit">
Send
</button>
</div>
</form>
<div if={ state.isOnline }>
<button class="button button--full button--danger center w-100 m-bottom-0" type="button" onclick={ (event) => { handleLogout(event) } }>
Logout
</button>
</diV>
</div>
</div>
<script>
import * as riot from 'riot'
import FormValidator from '@tiny-components/validator/src/formValidator.js'
import FieldError from '@tiny-components/validator/src/fieldError.riot'
riot.register('field-error', FieldError)
import xmppStore from './../stores/xmpp.js'
/**
* show login form to connect
*
*/
export default {
state: {
isLoading: false,
isOnline: false,
validator: false
},
onMounted() {
this.createForm()
xmppStore.on('error', (error) => {
console.log(error)
})
xmppStore.on('online', () => {
this.isLoading = false
this.state.isOnline = true
this.state.validator = false
this.update()
})
xmppStore.on('offline', () => {
this.isLoading = false
this.state.isOnline = false
this.update()
this.createForm()
})
},
/**
*
*
*/
createForm() {
this.state.validator = new FormValidator(this.$('form'), {
'service': {
'presence': true
},
'username': {
'presence': true
},
'password': {
'presence': true
}
}, true)
this.state.validator.onError((event) => {
this.isLoading = false
this.update()
})
this.state.validator.onSuccess((event, data) => {
event.preventDefault()
this.isLoading = true
this.update()
xmppStore.login(data.username, data.password, data.service)
})
},
/**
*
*
*/
handleLogout()
{
xmppStore.logout()
}
}
</script>
</xmpp-login>

@ -0,0 +1,12 @@
import * as riot from 'riot'
import XmppLogin from './components/xmpp-login.riot'
import XmppContacts from './components/xmpp-contacts.riot'
// register components
riot.register('xmpp-login', XmppLogin)
riot.register('xmpp-contacts', XmppContacts)
// mount components
riot.mount('xmpp-login')
riot.mount('xmpp-contacts')

@ -0,0 +1,49 @@
import { client, xml, jid } from '@xmpp/client'
import observable from '@riotjs/observable'
/**
* NotificationService
*
*
*/
export default observable({
login(username, password, service) {
// don't login twice
if (this.xmpp) {
return
}
this.xmpp = client({
service: service,
username: username,
password: password
})
this.xmpp.on('error', (error) => {
this.xmpp = false
this.trigger('error', error)
})
// handle if client goes online
this.xmpp.on('online', (address) => {
this.trigger('online', address)
})
this.xmpp.on('offline', () => {
this.xmpp = false
this.trigger('offline')
})
// connect
this.xmpp.start()
},
logout()
{
this.xmpp.stop()
}
})

@ -0,0 +1,9 @@
@import
'@tiny-components/plain-ui/src/scss/plain-ui';
ul {
list-style: none !important;
padding: 0 !important;
}

@ -0,0 +1,81 @@
const mix = require('laravel-mix')
const path = require('path')
require('laravel-mix-purgecss')
// plugins
const SvgSpritemapPlugin = require('svg-spritemap-webpack-plugin')
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel applications. By default, we are compiling the CSS
| file for the application as well as bundling up all the JS files.
|
*/
mix.webpackConfig({
module: {
rules: [{
test: /\.riot$/,
use: [{
loader: '@riotjs/webpack-loader',
options: {
hot: false
}
}]
}
]},
plugins: [
new SvgSpritemapPlugin('./node_modules/@tiny-components/plain-ui/src/icons/mono-icons/svg/*.svg', {
output: {
filename: 'public/symbol-defs.svg',
chunk: {
keep: true
},
svgo: {
plugins: [{
name: 'convertStyleToAttrs',
active: true
},{
name: 'removeStyleElement',
active: true
}, {
name: 'removeAttrs',
params: {
attrs: 'fill'
}
}]
}
},
sprite: {
prefix: 'icon-'
}
})
]
})
mix
.setPublicPath('./')
.js('src/js/script.js', 'public/js')
.sass('src/scss/styles.scss', 'public/css')
.purgeCss({
extend: {
content: [
path.join(__dirname, 'public/index.html'),
path.join(__dirname, 'src/js/**/*.riot')
]
}
})
.options({
terser: {
extractComments: false,
},
processCssUrls: false
})
.copyDirectory('node_modules/@tiny-components/plain-ui/src/fonts/IBM*', 'public/css')
.version()
Loading…
Cancel
Save