SlideShare a Scribd company logo
1 of 14
Copyright © 2016 M/Gateway Developments Ltd
EWD 3 Training Course
Part 13
Putting everything so far into
practice in QEWD
Rob Tweed
Director, M/Gateway Developments Ltd
Twitter: @rtweed
Copyright © 2016 M/Gateway Developments Ltd
Let’s put it all into practice
• Try cutting and pasting the following
example code
• Then try running it!
Copyright © 2016 M/Gateway Developments Ltd
Where your files go: a reminder
• Windows & Caché:
– Front-end HTML, JavaScript, CSS files:
• C:qewdwww{applicationName}
– eg:
– c:qewdwwwdemo1index.html
– c:qewdwwwdemo1app.js
– Back-end QEWD handler functions:
• C:qewdnode_modules{application}.js eg:
– C:qewdnode_modulesdemo1.js
Copyright © 2016 M/Gateway Developments Ltd
Where your files go: a reminder
• Linux & Raspberry Pi:
– Front-end HTML, JavaScript, CSS files:
• ~/qewd/www/{applicationName}
– eg:
– ~/qewd/www/demo1/index.html
– ~/qewd/www/demo1/app.js
– Back-end QEWD handler functions:
• ~/qewd/node_modules/{application}.js eg:
– ~/qewd/node_modules/demo1.js
Copyright © 2016 M/Gateway Developments Ltd
Simple Login Example
• index.html
<html>
<head>
<title>Demo ewd-xpress application</title>
<link href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet" />
</head>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="/ewd-client.js"></script>
<script src="app.js"></script>
<table id="loginForm">
<tr>
<td>Username:</td>
<td><input type="text" id="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" id="password" /></td>
</tr>
<tr>
<td colspan="2">
<button id="loginBtn">Login</button>
</td>
</tr>
</table>
<br /><br />
<button id="testBtn">Click Me</button>
</body>
</html>
Copyright © 2016 M/Gateway Developments Ltd
Simple Login Example
• Front-end:
– app.js
$(document).ready(function() {
EWD.log = true;
EWD.on('ewd-registered', function() {
EWD.on('error', function(responseObj) {
toastr.error(responseObj.message.error);
});
EWD.on('intermediate', function(responseObj) {
toastr.info('Intermediate response: ' + responseObj.message.date);
});
$('#testBtn').on('click', function(e) {
var message = {type: 'testButton'};
EWD.send(message, function(responseObj) {
if (!responseObj.message.error) toastr.info(JSON.stringify(responseObj.message));
});
});
$('#loginBtn').on('click', function(e) {
var username = $('#username').val();
if (username === '') {
toastr.error('You must enter a username');
return;
}
var password = $('#password').val()
if (password === '') {
toastr.error('You must enter a password');
return;
}
var message = {
type: 'login',
params: {
username: username,
password: password
}
};
EWD.send(message, function(responseObj) {
if (!responseObj.message.error) $('#loginForm').hide();
});
});
});
EWD.start('demo1', $, io);
});
Copyright © 2016 M/Gateway Developments Ltd
Simple Login Example
• back-end:
– demo1.js
function checkLogin(username, password) {
// hard-coded version for now
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true};
}
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You are already logged in!'});
return;
}
var username = messageObj.params.username;
if (username === '') {
finished({error: 'You must enter a username'});
return;
}
var password = messageObj.params.password;
if (password === '') {
finished({error: 'You must enter a password'});
return;
}
var status = checkLogin(username, password);
if (status.ok) {
session.authenticated = true;
finished({ok: true});
}
else {
finished({error: status.error});
}
},
testButton: function(messageObj, session, send, finished) {
if (!session.authenticated) {
finished({error: 'You are not yet logged in!'});
return;
}
send({
type: 'intermediate',
foo: 'bar',
date: new Date().toString()
});
finished({
ok: 'testButton message was processed successfully!'
});
}
}
};
Copyright © 2016 M/Gateway Developments Ltd
Add logout and more sophistication
Copyright © 2016 M/Gateway Developments Ltd
Login Example v2
• Index.html <html>
<head>
<title>Demo ewd-xpress application</title>
<link href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet" />
</head>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="/ewd-client.js"></script>
<script src="app.js"></script>
<table id="loginForm">
<tr>
<td>Username:</td>
<td><input type="text" id="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" id="password" /></td>
</tr>
<tr>
<td colspan="2">
<button id="loginBtn">Login</button>
</td>
</tr>
</table>
<br /><br />
<button id="testBtn">Click Me</button>
<br /><br />
<button id="logoutBtn">Logout</button>
</body>
</html>
Copyright © 2016 M/Gateway Developments Ltd
Login Example v2
• app.js
$(document).ready(function() {
EWD.log = true;
// hide the login form until its safe for user to log in
$('#loginForm').hide();
$('#logoutBtn').hide();
EWD.on('ewd-registered', function() {
EWD.on('error', function(responseObj) {
toastr.error(responseObj.message.error);
});
EWD.on('intermediate', function(responseObj) {
toastr.info('Intermediate response: ' + responseObj.message.date);
});
$('#testBtn').on('click', function(e) {
var message = {type: 'testButton'};
EWD.send(message, function(responseObj) {
if (!responseObj.message.error) toastr.info(JSON.stringify(responseObj.message));
});
});
$('#loginBtn').on('click', function(e) {
var username = $('#username').val();
if (username === '') {
toastr.error('You must enter a username');
return;
}
var password = $('#password').val()
if (password === '') {
toastr.error('You must enter a password');
return;
}
var message = {
type: 'login',
params: {
username: username,
password: password
}
};
EWD.send(message, function(responseObj) {
if (!responseObj.message.error) {
$('#loginForm').hide();
$('#logoutBtn').show();
}
});
});
$('#logoutBtn').on('click', function(e) {
EWD.disconnectSocket();
});
EWD.on('socketDisconnected', function() {
toastr.info('You have been logged out');
setTimeout(function() {
// reload index.html so a clean new session begins
location.reload();
}, 1000);
});
// safe for user to login now so reveal the form
$('#loginForm').show();
});
EWD.start('demo1', $, io);
});
Copyright © 2016 M/Gateway Developments Ltd
Login Example v2
• demo1.js
function checkLogin(username, password) {
// hard-coded version for now
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true};
}
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You are already logged in!'});
return;
}
var username = messageObj.params.username;
if (username === '') {
finished({error: 'You must enter a username'});
return;
}
var password = messageObj.params.password;
if (password === '') {
finished({error: 'You must enter a password'});
return;
}
var status = checkLogin.call(this, username, password);
if (status.ok) {
session.authenticated = true;
session.timeout = 3600;
session.updateExpiry();
finished({ok: true});
}
else {
finished({error: status.error});
}
},
testButton: function(messageObj, session, send, finished) {
if (!session.authenticated) {
finished({error: 'You are not yet logged in!'});
return;
}
send({
type: 'intermediate',
foo: 'bar',
date: new Date().toString()
});
finished({
ok: 'testButton message was processed successfully!'
});
}
}
};
Update session
timeout & expiry
Copyright © 2016 M/Gateway Developments Ltd
Login Example v2
• demo1.js
function checkLogin(username, password) {
// hard-coded version for now
if (username !== 'rob') return {error: 'Invalid username'};
if (password !== 'secret') return {error: 'Invalid password'};
return {ok: true};
}
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You are already logged in!'});
return;
}
var username = messageObj.params.username;
if (username === '') {
finished({error: 'You must enter a username'});
return;
}
var password = messageObj.params.password;
if (password === '') {
finished({error: 'You must enter a password'});
return;
}
var status = checkLogin.call(this, username, password);
if (status.ok) {
session.authenticated = true;
session.timeout = 3600;
session.updateExpiry();
finished({ok: true});
}
else {
finished({error: status.error});
}
},
testButton: function(messageObj, session, send, finished) {
if (!session.authenticated) {
finished({error: 'You are not yet logged in!'});
return;
}
send({
type: 'intermediate',
foo: 'bar',
date: new Date().toString()
});
finished({
ok: 'testButton message was processed successfully!'
});
}
}
};
Note: using call so this is
the context inside checkLogin()
Copyright © 2016 M/Gateway Developments Ltd
Login Example v2
• demo1.js
function checkLogin(username, password) {
var status = this.db.function({
function: 'login^security',
arguments: [username, password]
});
if (status == 1) return {ok: true};
return {error: 'Invalid login attempt};
}
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You are already logged in!'});
return;
}
var username = messageObj.params.username;
if (username === '') {
finished({error: 'You must enter a username'});
return;
}
var password = messageObj.params.password;
if (password === '') {
finished({error: 'You must enter a password'});
return;
}
var status = checkLogin.call(this, username, password);
if (status.ok) {
session.authenticated = true;
session.timeout = 3600;
session.updateExpiry();
finished({ok: true});
}
else {
finished({error: status.error});
}
},
testButton: function(messageObj, session, send, finished) {
if (!session.authenticated) {
finished({error: 'You are not yet logged in!'});
return;
}
send({
type: 'intermediate',
foo: 'bar',
date: new Date().toString()
});
finished({
ok: 'testButton message was processed successfully!'
});
}
}
So we could invoke a legacy
Mumps/Cache function to
handle the login
Copyright © 2016 M/Gateway Developments Ltd
Login Example v2
• demo1.js
function checkLogin(username, password) {
var auth = new this.documentStore.DocumentNode('authentication');
if (!auth.$(username).exists return {error: 'Invalid username'};
if (auth.$username.$('password').value === password) return {ok: true};
return {error: 'Invalid password};
}
module.exports = {
handlers: {
login: function(messageObj, session, send, finished) {
if (session.authenticated) {
finished({error: 'You are already logged in!'});
return;
}
var username = messageObj.params.username;
if (username === '') {
finished({error: 'You must enter a username'});
return;
}
var password = messageObj.params.password;
if (password === '') {
finished({error: 'You must enter a password'});
return;
}
var status = checkLogin.call(this, username, password);
if (status.ok) {
session.authenticated = true;
session.timeout = 3600;
session.updateExpiry();
finished({ok: true});
}
else {
finished({error: status.error});
}
},
testButton: function(messageObj, session, send, finished) {
if (!session.authenticated) {
finished({error: 'You are not yet logged in!'});
return;
}
send({
type: 'intermediate',
foo: 'bar',
date: new Date().toString()
});
finished({
ok: 'testButton message was processed successfully!'
});
}
}
};
Or we could access an
Authentication document

More Related Content

What's hot

EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...Rob Tweed
 
EWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging PatternEWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging PatternRob Tweed
 
EWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User AuthenticationEWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User AuthenticationRob Tweed
 
EWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD ServicesEWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD ServicesRob Tweed
 
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST ServicesEWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST ServicesRob Tweed
 
EWD 3 Training Course Part 12: QEWD Session Timeout Control
EWD 3 Training Course Part 12: QEWD Session Timeout ControlEWD 3 Training Course Part 12: QEWD Session Timeout Control
EWD 3 Training Course Part 12: QEWD Session Timeout ControlRob Tweed
 
EWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a ServiceEWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a ServiceRob Tweed
 
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...Rob Tweed
 
Beyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisBeyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisFastly
 
Node JS Express : Steps to Create Restful Web App
Node JS Express : Steps to Create Restful Web AppNode JS Express : Steps to Create Restful Web App
Node JS Express : Steps to Create Restful Web AppEdureka!
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackIgnacio Martín
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsMatthew Beale
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play appsYevgeniy Brikman
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server renderingZiad Saab
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applicationsAstrails
 

What's hot (20)

EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
EWD 3 Training Course Part 36: Accessing REST and Web Services from a QEWD ap...
 
EWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging PatternEWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
EWD 3 Training Course Part 7: Applying the QEWD Messaging Pattern
 
EWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User AuthenticationEWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User Authentication
 
EWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD ServicesEWD 3 Training Course Part 16: QEWD Services
EWD 3 Training Course Part 16: QEWD Services
 
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST ServicesEWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
EWD 3 Training Course Part 43: Using JSON Web Tokens with QEWD REST Services
 
EWD 3 Training Course Part 12: QEWD Session Timeout Control
EWD 3 Training Course Part 12: QEWD Session Timeout ControlEWD 3 Training Course Part 12: QEWD Session Timeout Control
EWD 3 Training Course Part 12: QEWD Session Timeout Control
 
EWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a ServiceEWD 3 Training Course Part 29: Running QEWD as a Service
EWD 3 Training Course Part 29: Running QEWD as a Service
 
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
EWD 3 Training Course Part 37: Building a React.js application with ewd-xpres...
 
Beyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic AnalysisBeyond Breakpoints: A Tour of Dynamic Analysis
Beyond Breakpoints: A Tour of Dynamic Analysis
 
Vuejs testing
Vuejs testingVuejs testing
Vuejs testing
 
Node JS Express : Steps to Create Restful Web App
Node JS Express : Steps to Create Restful Web AppNode JS Express : Steps to Create Restful Web App
Node JS Express : Steps to Create Restful Web App
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
Composable and streamable Play apps
Composable and streamable Play appsComposable and streamable Play apps
Composable and streamable Play apps
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
React
React React
React
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server rendering
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
 

Viewers also liked

EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...
EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...
EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...Rob Tweed
 
EWD 3 Training Course Part 2: EWD 3 Overview
EWD 3 Training Course Part 2: EWD 3 OverviewEWD 3 Training Course Part 2: EWD 3 Overview
EWD 3 Training Course Part 2: EWD 3 OverviewRob Tweed
 
EWD 3 Training Course Part 8: Anatomy of the QEWD Messaging Cycle
EWD 3 Training Course Part 8: Anatomy of the QEWD Messaging CycleEWD 3 Training Course Part 8: Anatomy of the QEWD Messaging Cycle
EWD 3 Training Course Part 8: Anatomy of the QEWD Messaging CycleRob Tweed
 
EWD 3 Training Course Part 4: Installing & Configuring QEWD
EWD 3 Training Course Part 4: Installing & Configuring QEWDEWD 3 Training Course Part 4: Installing & Configuring QEWD
EWD 3 Training Course Part 4: Installing & Configuring QEWDRob Tweed
 
EWD 3 Training Course Part 3: Summary of EWD 3 Modules
EWD 3 Training Course Part 3: Summary of EWD 3 ModulesEWD 3 Training Course Part 3: Summary of EWD 3 Modules
EWD 3 Training Course Part 3: Summary of EWD 3 ModulesRob Tweed
 
EWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and ResponsesEWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and ResponsesRob Tweed
 
EWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage DatabasesEWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage DatabasesRob Tweed
 
EWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is StartedEWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is StartedRob Tweed
 
EWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD SessionEWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD SessionRob Tweed
 
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global StorageEWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global StorageRob Tweed
 
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWDEWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWDRob Tweed
 
EWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIsEWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIsRob Tweed
 
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWDEWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWDRob Tweed
 
EWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session LockingEWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session LockingRob Tweed
 
EWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORSEWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORSRob Tweed
 
EWD 3 Training Course Part 25: Document Database Capabilities
EWD 3 Training Course Part 25: Document Database CapabilitiesEWD 3 Training Course Part 25: Document Database Capabilities
EWD 3 Training Course Part 25: Document Database CapabilitiesRob Tweed
 
EWD 3 Training Course Part 24: Traversing a Document's Leaf Nodes
EWD 3 Training Course Part 24: Traversing a Document's Leaf NodesEWD 3 Training Course Part 24: Traversing a Document's Leaf Nodes
EWD 3 Training Course Part 24: Traversing a Document's Leaf NodesRob Tweed
 
EWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven IndexingEWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven IndexingRob Tweed
 
EWD 3 Training Course Part 21: Persistent JavaScript Objects
EWD 3 Training Course Part 21: Persistent JavaScript ObjectsEWD 3 Training Course Part 21: Persistent JavaScript Objects
EWD 3 Training Course Part 21: Persistent JavaScript ObjectsRob Tweed
 
EWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient ModeEWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient ModeRob Tweed
 

Viewers also liked (20)

EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...
EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...
EWD 3 Training Course Part 1: How Node.js Integrates With Global Storage Data...
 
EWD 3 Training Course Part 2: EWD 3 Overview
EWD 3 Training Course Part 2: EWD 3 OverviewEWD 3 Training Course Part 2: EWD 3 Overview
EWD 3 Training Course Part 2: EWD 3 Overview
 
EWD 3 Training Course Part 8: Anatomy of the QEWD Messaging Cycle
EWD 3 Training Course Part 8: Anatomy of the QEWD Messaging CycleEWD 3 Training Course Part 8: Anatomy of the QEWD Messaging Cycle
EWD 3 Training Course Part 8: Anatomy of the QEWD Messaging Cycle
 
EWD 3 Training Course Part 4: Installing & Configuring QEWD
EWD 3 Training Course Part 4: Installing & Configuring QEWDEWD 3 Training Course Part 4: Installing & Configuring QEWD
EWD 3 Training Course Part 4: Installing & Configuring QEWD
 
EWD 3 Training Course Part 3: Summary of EWD 3 Modules
EWD 3 Training Course Part 3: Summary of EWD 3 ModulesEWD 3 Training Course Part 3: Summary of EWD 3 Modules
EWD 3 Training Course Part 3: Summary of EWD 3 Modules
 
EWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and ResponsesEWD 3 Training Course Part 9: Complex QEWD Messages and Responses
EWD 3 Training Course Part 9: Complex QEWD Messages and Responses
 
EWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage DatabasesEWD 3 Training Course Part 17: Introduction to Global Storage Databases
EWD 3 Training Course Part 17: Introduction to Global Storage Databases
 
EWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is StartedEWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
EWD 3 Training Course Part 6: What Happens when a QEWD Application is Started
 
EWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD SessionEWD 3 Training Course Part 27: The QEWD Session
EWD 3 Training Course Part 27: The QEWD Session
 
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global StorageEWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
EWD 3 Training Course Part 18: Modelling NoSQL Databases using Global Storage
 
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWDEWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
EWD 3 Training Course Part 28: Integrating Legacy Mumps Code with QEWD
 
EWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIsEWD 3 Training Course Part 19: The cache.node APIs
EWD 3 Training Course Part 19: The cache.node APIs
 
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWDEWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
EWD 3 Training Course Part 15: Using a Framework other than jQuery with QEWD
 
EWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session LockingEWD 3 Training Course Part 35: QEWD Session Locking
EWD 3 Training Course Part 35: QEWD Session Locking
 
EWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORSEWD 3 Training Course Part 33: Configuring QEWD to use CORS
EWD 3 Training Course Part 33: Configuring QEWD to use CORS
 
EWD 3 Training Course Part 25: Document Database Capabilities
EWD 3 Training Course Part 25: Document Database CapabilitiesEWD 3 Training Course Part 25: Document Database Capabilities
EWD 3 Training Course Part 25: Document Database Capabilities
 
EWD 3 Training Course Part 24: Traversing a Document's Leaf Nodes
EWD 3 Training Course Part 24: Traversing a Document's Leaf NodesEWD 3 Training Course Part 24: Traversing a Document's Leaf Nodes
EWD 3 Training Course Part 24: Traversing a Document's Leaf Nodes
 
EWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven IndexingEWD 3 Training Course Part 26: Event-driven Indexing
EWD 3 Training Course Part 26: Event-driven Indexing
 
EWD 3 Training Course Part 21: Persistent JavaScript Objects
EWD 3 Training Course Part 21: Persistent JavaScript ObjectsEWD 3 Training Course Part 21: Persistent JavaScript Objects
EWD 3 Training Course Part 21: Persistent JavaScript Objects
 
EWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient ModeEWD 3 Training Course Part 34: QEWD Resilient Mode
EWD 3 Training Course Part 34: QEWD Resilient Mode
 

Similar to EWD 3 Training Course Part 13: Putting Everything so far into Practice using QEWD

How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainCodemotion Tel Aviv
 
Join the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsJoin the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsSeth McLaughlin
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiRan Mizrahi
 
Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16Nikolay Kozhukharenko
 
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...Ivan Čukić
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for youSimon Willison
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)Domenic Denicola
 
05 communications
05 communications05 communications
05 communicationsmemeapps
 
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...Francois Marier
 
Live Streaming & Server Sent Events
Live Streaming & Server Sent EventsLive Streaming & Server Sent Events
Live Streaming & Server Sent Eventstkramar
 
2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript SecurityJohannes Hoppe
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in SwiftPeter Friese
 
Creating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdfCreating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdfShaiAlmog1
 
Serverless Ballerina
Serverless BallerinaServerless Ballerina
Serverless BallerinaBallerina
 

Similar to EWD 3 Training Course Part 13: Putting Everything so far into Practice using QEWD (20)

How to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrainHow to actually use promises - Jakob Mattsson, FishBrain
How to actually use promises - Jakob Mattsson, FishBrain
 
Join the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsJoin the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.js
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16Koajs as an alternative to Express - OdessaJs'16
Koajs as an alternative to Express - OdessaJs'16
 
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
 
Testing in JavaScript
Testing in JavaScriptTesting in JavaScript
Testing in JavaScript
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
05 communications
05 communications05 communications
05 communications
 
Webauthn Tutorial
Webauthn TutorialWebauthn Tutorial
Webauthn Tutorial
 
Service Workers
Service WorkersService Workers
Service Workers
 
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...
Building Persona: federated and privacy-sensitive identity for the Web (LCA 2...
 
Live Streaming & Server Sent Events
Live Streaming & Server Sent EventsLive Streaming & Server Sent Events
Live Streaming & Server Sent Events
 
2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security2013-06-25 - HTML5 & JavaScript Security
2013-06-25 - HTML5 & JavaScript Security
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 
Creating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdfCreating a Facebook Clone - Part XXVII - Transcript.pdf
Creating a Facebook Clone - Part XXVII - Transcript.pdf
 
Serverless Ballerina
Serverless BallerinaServerless Ballerina
Serverless Ballerina
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 

More from Rob Tweed

Data Persistence as a Language Feature
Data Persistence as a Language FeatureData Persistence as a Language Feature
Data Persistence as a Language FeatureRob Tweed
 
LNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It TooLNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It TooRob Tweed
 
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService FunctionalityEWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService FunctionalityRob Tweed
 
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.jsEWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.jsRob Tweed
 
QEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServicesQEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServicesRob Tweed
 
QEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It TooQEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It TooRob Tweed
 
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Servicesewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST ServicesRob Tweed
 
qewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle Tierqewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle TierRob Tweed
 
EWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker ApplianceEWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker ApplianceRob Tweed
 
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPSEWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPSRob Tweed
 
EWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST ServicesEWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST ServicesRob Tweed
 
EWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD ApplicationsEWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD ApplicationsRob Tweed
 

More from Rob Tweed (13)

QEWD Update
QEWD UpdateQEWD Update
QEWD Update
 
Data Persistence as a Language Feature
Data Persistence as a Language FeatureData Persistence as a Language Feature
Data Persistence as a Language Feature
 
LNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It TooLNUG: Having Your Node.js Cake and Eating It Too
LNUG: Having Your Node.js Cake and Eating It Too
 
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService FunctionalityEWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
EWD 3 Training Course Part 45: Using QEWD's Advanced MicroService Functionality
 
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.jsEWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
EWD 3 Training Course Part 44: Creating MicroServices with QEWD.js
 
QEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServicesQEWD.js, JSON Web Tokens & MicroServices
QEWD.js, JSON Web Tokens & MicroServices
 
QEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It TooQEWD.js: Have your Node.js Cake and Eat It Too
QEWD.js: Have your Node.js Cake and Eat It Too
 
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Servicesewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
ewd-qoper8-vistarpc: Exposing VistA's RPCs as REST Services
 
qewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle Tierqewd-ripple: The Ripple OSI Middle Tier
qewd-ripple: The Ripple OSI Middle Tier
 
EWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker ApplianceEWD 3 Training Course Part 42: The QEWD Docker Appliance
EWD 3 Training Course Part 42: The QEWD Docker Appliance
 
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPSEWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
EWD 3 Training Course Part 32: Configuring QEWD to use SSL/HTTPS
 
EWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST ServicesEWD 3 Training Course Part 31: Using QEWD for Web and REST Services
EWD 3 Training Course Part 31: Using QEWD for Web and REST Services
 
EWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD ApplicationsEWD 3 Training Course Part 30: Modularising QEWD Applications
EWD 3 Training Course Part 30: Modularising QEWD Applications
 

Recently uploaded

2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics
 
SoftTeco - Software Development Company Profile
SoftTeco - Software Development Company ProfileSoftTeco - Software Development Company Profile
SoftTeco - Software Development Company Profileakrivarotava
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 

Recently uploaded (20)

2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024
 
SoftTeco - Software Development Company Profile
SoftTeco - Software Development Company ProfileSoftTeco - Software Development Company Profile
SoftTeco - Software Development Company Profile
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 

EWD 3 Training Course Part 13: Putting Everything so far into Practice using QEWD

  • 1. Copyright © 2016 M/Gateway Developments Ltd EWD 3 Training Course Part 13 Putting everything so far into practice in QEWD Rob Tweed Director, M/Gateway Developments Ltd Twitter: @rtweed
  • 2. Copyright © 2016 M/Gateway Developments Ltd Let’s put it all into practice • Try cutting and pasting the following example code • Then try running it!
  • 3. Copyright © 2016 M/Gateway Developments Ltd Where your files go: a reminder • Windows & Caché: – Front-end HTML, JavaScript, CSS files: • C:qewdwww{applicationName} – eg: – c:qewdwwwdemo1index.html – c:qewdwwwdemo1app.js – Back-end QEWD handler functions: • C:qewdnode_modules{application}.js eg: – C:qewdnode_modulesdemo1.js
  • 4. Copyright © 2016 M/Gateway Developments Ltd Where your files go: a reminder • Linux & Raspberry Pi: – Front-end HTML, JavaScript, CSS files: • ~/qewd/www/{applicationName} – eg: – ~/qewd/www/demo1/index.html – ~/qewd/www/demo1/app.js – Back-end QEWD handler functions: • ~/qewd/node_modules/{application}.js eg: – ~/qewd/node_modules/demo1.js
  • 5. Copyright © 2016 M/Gateway Developments Ltd Simple Login Example • index.html <html> <head> <title>Demo ewd-xpress application</title> <link href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet" /> </head> <body> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script src="/ewd-client.js"></script> <script src="app.js"></script> <table id="loginForm"> <tr> <td>Username:</td> <td><input type="text" id="username" /></td> </tr> <tr> <td>Password:</td> <td><input type="password" id="password" /></td> </tr> <tr> <td colspan="2"> <button id="loginBtn">Login</button> </td> </tr> </table> <br /><br /> <button id="testBtn">Click Me</button> </body> </html>
  • 6. Copyright © 2016 M/Gateway Developments Ltd Simple Login Example • Front-end: – app.js $(document).ready(function() { EWD.log = true; EWD.on('ewd-registered', function() { EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); }); EWD.on('intermediate', function(responseObj) { toastr.info('Intermediate response: ' + responseObj.message.date); }); $('#testBtn').on('click', function(e) { var message = {type: 'testButton'}; EWD.send(message, function(responseObj) { if (!responseObj.message.error) toastr.info(JSON.stringify(responseObj.message)); }); }); $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val() if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: 'login', params: { username: username, password: password } }; EWD.send(message, function(responseObj) { if (!responseObj.message.error) $('#loginForm').hide(); }); }); }); EWD.start('demo1', $, io); });
  • 7. Copyright © 2016 M/Gateway Developments Ltd Simple Login Example • back-end: – demo1.js function checkLogin(username, password) { // hard-coded version for now if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true}; } module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You are already logged in!'}); return; } var username = messageObj.params.username; if (username === '') { finished({error: 'You must enter a username'}); return; } var password = messageObj.params.password; if (password === '') { finished({error: 'You must enter a password'}); return; } var status = checkLogin(username, password); if (status.ok) { session.authenticated = true; finished({ok: true}); } else { finished({error: status.error}); } }, testButton: function(messageObj, session, send, finished) { if (!session.authenticated) { finished({error: 'You are not yet logged in!'}); return; } send({ type: 'intermediate', foo: 'bar', date: new Date().toString() }); finished({ ok: 'testButton message was processed successfully!' }); } } };
  • 8. Copyright © 2016 M/Gateway Developments Ltd Add logout and more sophistication
  • 9. Copyright © 2016 M/Gateway Developments Ltd Login Example v2 • Index.html <html> <head> <title>Demo ewd-xpress application</title> <link href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet" /> </head> <body> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script src="/ewd-client.js"></script> <script src="app.js"></script> <table id="loginForm"> <tr> <td>Username:</td> <td><input type="text" id="username" /></td> </tr> <tr> <td>Password:</td> <td><input type="password" id="password" /></td> </tr> <tr> <td colspan="2"> <button id="loginBtn">Login</button> </td> </tr> </table> <br /><br /> <button id="testBtn">Click Me</button> <br /><br /> <button id="logoutBtn">Logout</button> </body> </html>
  • 10. Copyright © 2016 M/Gateway Developments Ltd Login Example v2 • app.js $(document).ready(function() { EWD.log = true; // hide the login form until its safe for user to log in $('#loginForm').hide(); $('#logoutBtn').hide(); EWD.on('ewd-registered', function() { EWD.on('error', function(responseObj) { toastr.error(responseObj.message.error); }); EWD.on('intermediate', function(responseObj) { toastr.info('Intermediate response: ' + responseObj.message.date); }); $('#testBtn').on('click', function(e) { var message = {type: 'testButton'}; EWD.send(message, function(responseObj) { if (!responseObj.message.error) toastr.info(JSON.stringify(responseObj.message)); }); }); $('#loginBtn').on('click', function(e) { var username = $('#username').val(); if (username === '') { toastr.error('You must enter a username'); return; } var password = $('#password').val() if (password === '') { toastr.error('You must enter a password'); return; } var message = { type: 'login', params: { username: username, password: password } }; EWD.send(message, function(responseObj) { if (!responseObj.message.error) { $('#loginForm').hide(); $('#logoutBtn').show(); } }); }); $('#logoutBtn').on('click', function(e) { EWD.disconnectSocket(); }); EWD.on('socketDisconnected', function() { toastr.info('You have been logged out'); setTimeout(function() { // reload index.html so a clean new session begins location.reload(); }, 1000); }); // safe for user to login now so reveal the form $('#loginForm').show(); }); EWD.start('demo1', $, io); });
  • 11. Copyright © 2016 M/Gateway Developments Ltd Login Example v2 • demo1.js function checkLogin(username, password) { // hard-coded version for now if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true}; } module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You are already logged in!'}); return; } var username = messageObj.params.username; if (username === '') { finished({error: 'You must enter a username'}); return; } var password = messageObj.params.password; if (password === '') { finished({error: 'You must enter a password'}); return; } var status = checkLogin.call(this, username, password); if (status.ok) { session.authenticated = true; session.timeout = 3600; session.updateExpiry(); finished({ok: true}); } else { finished({error: status.error}); } }, testButton: function(messageObj, session, send, finished) { if (!session.authenticated) { finished({error: 'You are not yet logged in!'}); return; } send({ type: 'intermediate', foo: 'bar', date: new Date().toString() }); finished({ ok: 'testButton message was processed successfully!' }); } } }; Update session timeout & expiry
  • 12. Copyright © 2016 M/Gateway Developments Ltd Login Example v2 • demo1.js function checkLogin(username, password) { // hard-coded version for now if (username !== 'rob') return {error: 'Invalid username'}; if (password !== 'secret') return {error: 'Invalid password'}; return {ok: true}; } module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You are already logged in!'}); return; } var username = messageObj.params.username; if (username === '') { finished({error: 'You must enter a username'}); return; } var password = messageObj.params.password; if (password === '') { finished({error: 'You must enter a password'}); return; } var status = checkLogin.call(this, username, password); if (status.ok) { session.authenticated = true; session.timeout = 3600; session.updateExpiry(); finished({ok: true}); } else { finished({error: status.error}); } }, testButton: function(messageObj, session, send, finished) { if (!session.authenticated) { finished({error: 'You are not yet logged in!'}); return; } send({ type: 'intermediate', foo: 'bar', date: new Date().toString() }); finished({ ok: 'testButton message was processed successfully!' }); } } }; Note: using call so this is the context inside checkLogin()
  • 13. Copyright © 2016 M/Gateway Developments Ltd Login Example v2 • demo1.js function checkLogin(username, password) { var status = this.db.function({ function: 'login^security', arguments: [username, password] }); if (status == 1) return {ok: true}; return {error: 'Invalid login attempt}; } module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You are already logged in!'}); return; } var username = messageObj.params.username; if (username === '') { finished({error: 'You must enter a username'}); return; } var password = messageObj.params.password; if (password === '') { finished({error: 'You must enter a password'}); return; } var status = checkLogin.call(this, username, password); if (status.ok) { session.authenticated = true; session.timeout = 3600; session.updateExpiry(); finished({ok: true}); } else { finished({error: status.error}); } }, testButton: function(messageObj, session, send, finished) { if (!session.authenticated) { finished({error: 'You are not yet logged in!'}); return; } send({ type: 'intermediate', foo: 'bar', date: new Date().toString() }); finished({ ok: 'testButton message was processed successfully!' }); } } So we could invoke a legacy Mumps/Cache function to handle the login
  • 14. Copyright © 2016 M/Gateway Developments Ltd Login Example v2 • demo1.js function checkLogin(username, password) { var auth = new this.documentStore.DocumentNode('authentication'); if (!auth.$(username).exists return {error: 'Invalid username'}; if (auth.$username.$('password').value === password) return {ok: true}; return {error: 'Invalid password}; } module.exports = { handlers: { login: function(messageObj, session, send, finished) { if (session.authenticated) { finished({error: 'You are already logged in!'}); return; } var username = messageObj.params.username; if (username === '') { finished({error: 'You must enter a username'}); return; } var password = messageObj.params.password; if (password === '') { finished({error: 'You must enter a password'}); return; } var status = checkLogin.call(this, username, password); if (status.ok) { session.authenticated = true; session.timeout = 3600; session.updateExpiry(); finished({ok: true}); } else { finished({error: status.error}); } }, testButton: function(messageObj, session, send, finished) { if (!session.authenticated) { finished({error: 'You are not yet logged in!'}); return; } send({ type: 'intermediate', foo: 'bar', date: new Date().toString() }); finished({ ok: 'testButton message was processed successfully!' }); } } }; Or we could access an Authentication document