Skip to content
This repository was archived by the owner on Mar 13, 2022. It is now read-only.

Commit 8e014fe

Browse files
MichaelJColenothingismagick
authored andcommitted
Add an auth API that can be used on modal dialogs (#6)
* Add an auth API that can be used on modal dialogs * Working server. Still needs integration
1 parent eada49b commit 8e014fe

34 files changed

+4197
-0
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
Context:
3+
4+
For 3rd-party API's, we us /src/boot/axios.js
5+
6+
For our own API's, we use FeathersClient (socket.io & REST)
7+
https://docs.feathersjs.com/guides/basics/clients.html
8+
https://docs.feathersjs.com/api/authentication/client.html#appconfigureauthoptions
9+
10+
Our FeathersClient is in `/src/lib/feathersClient.js`
11+
and imported into `/src/store/index.js`
12+
which is imported by Quasar's build system. /src/quasar.conf.js setting(?)
13+
14+
Feathers-vuex integrates Vuex with FeathersClient:
15+
https://feathers-vuex.feathers-plus.com/auth-module.html
16+
17+
Feathers-Vuex proxies it's authentication/logout actions to FeathersClient
18+
https://github.com/feathers-plus/feathers-vuex/blob/master/src/auth-module/actions.js
19+
20+
The parameters for these actions are here:
21+
https://docs.feathersjs.com/api/authentication/client.html#appauthenticateoptions
22+
23+
In addition to this module, you can use FeathersVuex state in UI from here:
24+
https://feathers-vuex.feathers-plus.com/auth-module.html
25+
26+
27+
This module:
28+
29+
Create a Feathers Auth integration for Vue as a Quasar Boot Module.
30+
31+
// Use case: test if user is authenticated
32+
33+
if (Vue.$auth.currentUser()) { ... }
34+
35+
// Use case: get current user's email
36+
37+
name = Vue.$auth.currentUser("email") || "anonymous"
38+
39+
// Use case: Login
40+
41+
Vue.$auth.login({
42+
strategy: 'local',
43+
email: 'my@email.com',
44+
password: 'my-password'
45+
});
46+
47+
// Use case: Logout
48+
49+
// logs out and sends message
50+
let p = Vue.$auth.logout();
51+
// After logout, go home
52+
p.then(() => {
53+
// User data still in browser
54+
router.push({ name: "home"});
55+
// To clear user data, do a hard refresh/redirect - https://feathers-vuex.feathers-plus.com/common-patterns.html#clearing-data-upon-user-logout
56+
location && location.reload(true)
57+
});
58+
59+
*/
60+
61+
export default ({ app, router, store, Vue }) => {
62+
// Create the API demonstrated above
63+
const auth = {
64+
currentUser(prop) {
65+
let u = store.state.auth.user || false;
66+
if (u && prop) return u[prop];
67+
return u;
68+
},
69+
login(authData, quiet) {
70+
return store
71+
.dispatch("auth/authenticate", authData)
72+
.then(() => {
73+
Vue.prototype.$q.notify({
74+
message: "Right on, let's do this!",
75+
type: "info"
76+
});
77+
})
78+
.catch(err => {
79+
if (!quiet) {
80+
console.log(err);
81+
Vue.prototype.$q.notify({
82+
message: "There was a problem logging you in.",
83+
type: "error"
84+
});
85+
}
86+
});
87+
},
88+
logout(quiet) {
89+
return store.dispatch("auth/logout").then(() => {
90+
if (!quiet)
91+
Vue.prototype.$q.notify({
92+
message: "You've been logged out.",
93+
type: "info"
94+
});
95+
});
96+
},
97+
register(authData) {
98+
// FIXME why is this empty?
99+
}
100+
};
101+
102+
// Auth from JWT stored in browser before loading the app. true => suppress token not found error
103+
auth.login("jwt", true);
104+
105+
// Add API to Vue
106+
Vue.prototype.$auth = auth;
107+
108+
// If you would like to play with it in the console, uncomment this line:
109+
// console.log(auth);
110+
111+
// Then, in the console:
112+
/*
113+
temp1.login({
114+
strategy: "local",
115+
email: "feathers@example.com",
116+
password: "secret"
117+
})
118+
*/
119+
120+
// If you haven't created this user, see here:
121+
// https://docs.feathersjs.com/guides/chat/authentication.html
122+
// For this REST api endpoint
123+
/*
124+
curl 'http://localhost:3001/users/' -H 'Content-Type: application/json' --data-binary '{ "email": "feathers@example.com", "password": "secret" }'
125+
*/
126+
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import feathers from "@feathersjs/feathers";
2+
import auth from "@feathersjs/authentication-client";
3+
import { CookieStorage } from "cookie-storage";
4+
import restClient from "@feathersjs/rest-client";
5+
import axios from "axios";
6+
7+
import socketio from "@feathersjs/socketio-client";
8+
import io from "socket.io-client";
9+
let socketOptions = { transports: ["websocket"] };
10+
11+
// Production Config
12+
13+
let url = process.env.HOST_URL;
14+
15+
// In dev mode, use http://localhost:3000 as the URL.
16+
// Tried to set this up with https using nginx.conf.
17+
// Dev config Quasar HMR wants to use port from quasar.conf.js, even through it's served through a proxy on 443. This is the compromise.
18+
19+
if (["localhost:3000"].includes(window.location.host)) {
20+
// See quasar.conf.js
21+
url = "http://localhost:3001";
22+
socketOptions.rejectUnauthorized = false;
23+
}
24+
25+
const socket = io(url, socketOptions);
26+
const rest = restClient(url);
27+
28+
const storage = new CookieStorage();
29+
const feathersClient = feathers()
30+
.configure(socketio(socket))
31+
.configure(rest.axios(axios)) // FIXME needed?
32+
.configure(auth({ storage })); // See ... for options
33+
34+
export default feathersClient;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// This file is auto-magically imported into Quasar build system.
2+
3+
import Vue from "vue";
4+
import Vuex from "vuex";
5+
import feathersVuex from "feathers-vuex";
6+
import feathersClient from "../lib/feathersClient";
7+
8+
const { service, auth, FeathersVuex } = feathersVuex(feathersClient, {
9+
idField: "_id"
10+
nameStyle: 'short', // Determines the source of the module name. 'short' or 'path'
11+
enableEvents: true // Set to false to explicitly disable socket event handlers.
12+
});
13+
14+
Vue.use(Vuex);
15+
Vue.use(FeathersVuex);
16+
17+
export default function(/*{ ssrContext }*/) {
18+
return new Vuex.Store({
19+
// enable strict mode (adds overhead!) - dev mode only
20+
strict: process.env.DEV,
21+
// The state accessable in pages and components
22+
state: {
23+
myStuff: false
24+
},
25+
mutations: {
26+
MUTATE_STUFF(state, newStuff) {
27+
state.myStuff = newStuff;
28+
},
29+
},
30+
actions: {
31+
getNewStuff: async function(context) {
32+
// FIXME demonstrate using FeathersVuex here.
33+
return Promise.resolve({
34+
return 'hello world'
35+
})
36+
.then(stuff => {
37+
context.commit("MUTATE_STUFF", stuff);
38+
});
39+
},
40+
},
41+
plugins: [
42+
service("api/stuff"),
43+
service("api/users"),
44+
// Setup the auth plugin.
45+
auth({ userService: "users" }) // the api/ is implied by nameStyle: 'short', above. FIXME Verify
46+
]
47+
});
48+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[*.md]
13+
trim_trailing_whitespace = false
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"env": {
3+
"es6": true,
4+
"node": true,
5+
"mocha": true
6+
},
7+
"parserOptions": {
8+
"ecmaVersion": 2017
9+
},
10+
"extends": "eslint:recommended",
11+
"rules": {
12+
"indent": [
13+
"error",
14+
2
15+
],
16+
"linebreak-style": [
17+
"error",
18+
"unix"
19+
],
20+
"quotes": [
21+
"error",
22+
"single"
23+
],
24+
"semi": [
25+
"error",
26+
"always"
27+
]
28+
}
29+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Logs
2+
logs
3+
*.log
4+
5+
# Runtime data
6+
pids
7+
*.pid
8+
*.seed
9+
10+
# Directory for instrumented libs generated by jscoverage/JSCover
11+
lib-cov
12+
13+
# Coverage directory used by tools like istanbul
14+
coverage
15+
16+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17+
.grunt
18+
19+
# Compiled binary addons (http://nodejs.org/api/addons.html)
20+
build/Release
21+
22+
# Dependency directory
23+
# Commenting this out is preferred by some people, see
24+
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
25+
node_modules
26+
27+
# Users Environment Variables
28+
.lock-wscript
29+
30+
# IDEs and editors (shamelessly copied from @angular/cli's .gitignore)
31+
/.idea
32+
.project
33+
.classpath
34+
.c9/
35+
*.launch
36+
.settings/
37+
*.sublime-workspace
38+
39+
# IDE - VSCode
40+
.vscode/*
41+
!.vscode/settings.json
42+
!.vscode/tasks.json
43+
!.vscode/launch.json
44+
!.vscode/extensions.json
45+
46+
### Linux ###
47+
*~
48+
49+
# temporary files which can be created if a process still has a handle open of a deleted file
50+
.fuse_hidden*
51+
52+
# KDE directory preferences
53+
.directory
54+
55+
# Linux trash folder which might appear on any partition or disk
56+
.Trash-*
57+
58+
# .nfs files are created when an open file is removed but is still being accessed
59+
.nfs*
60+
61+
### OSX ###
62+
*.DS_Store
63+
.AppleDouble
64+
.LSOverride
65+
66+
# Icon must end with two \r
67+
Icon
68+
69+
70+
# Thumbnails
71+
._*
72+
73+
# Files that might appear in the root of a volume
74+
.DocumentRevisions-V100
75+
.fseventsd
76+
.Spotlight-V100
77+
.TemporaryItems
78+
.Trashes
79+
.VolumeIcon.icns
80+
.com.apple.timemachine.donotpresent
81+
82+
# Directories potentially created on remote AFP share
83+
.AppleDB
84+
.AppleDesktop
85+
Network Trash Folder
86+
Temporary Items
87+
.apdisk
88+
89+
### Windows ###
90+
# Windows thumbnail cache files
91+
Thumbs.db
92+
ehthumbs.db
93+
ehthumbs_vista.db
94+
95+
# Folder config file
96+
Desktop.ini
97+
98+
# Recycle Bin used on file shares
99+
$RECYCLE.BIN/
100+
101+
# Windows Installer files
102+
*.cab
103+
*.msi
104+
*.msm
105+
*.msp
106+
107+
# Windows shortcuts
108+
*.lnk
109+
110+
# Others
111+
lib/
112+
data/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Feathers
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

0 commit comments

Comments
 (0)