├── public
├── favicon.ico
├── tables.html
├── assets
│ └── style
│ │ └── application.css
├── frontend
│ └── app.jsx
└── index.html
├── src
├── middleware
│ ├── not-found-handler.js
│ ├── index.js
│ └── logger.js
├── index.js
├── services
│ ├── authentication
│ │ └── index.js
│ ├── index.js
│ ├── table
│ │ ├── hooks
│ │ │ └── index.js
│ │ └── index.js
│ └── user
│ │ ├── index.js
│ │ └── hooks
│ │ └── index.js
├── hooks
│ └── index.js
└── app.js
├── config
├── production.json
└── default.json
├── .editorconfig
├── test
├── services
│ ├── table
│ │ └── index.test.js
│ └── user
│ │ └── index.test.js
└── app.test.js
├── webpack.config.js
├── .jshintrc
├── .npmignore
├── .gitignore
├── LICENSE
├── README.md
└── package.json
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ekryski/feathers-poker/master/public/favicon.ico
--------------------------------------------------------------------------------
/src/middleware/not-found-handler.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const errors = require('feathers-errors');
4 |
5 | module.exports = function() {
6 | return function(req, res, next) {
7 | next(new errors.NotFound('Page not found'));
8 | };
9 | };
10 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const app = require('./app');
4 | const port = app.get('port');
5 | const server = app.listen(port);
6 |
7 | server.on('listening', () =>
8 | console.log(`Poker application started on ${app.get('host')}:${port}`)
9 | );
10 |
--------------------------------------------------------------------------------
/config/production.json:
--------------------------------------------------------------------------------
1 | {
2 | "host": "Poker-app.feathersjs.com",
3 | "port": 80,
4 | "nedb": "NEDB_BASE_PATH",
5 | "public": "../public/",
6 | "auth": {
7 | "token": {
8 | "secret": "FEATHERS_AUTH_SECRET"
9 | },
10 | "local": {}
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
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
14 |
--------------------------------------------------------------------------------
/src/services/authentication/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const authentication = require('feathers-authentication');
4 |
5 |
6 | module.exports = function() {
7 | const app = this;
8 |
9 | let config = app.get('auth');
10 |
11 | app.configure(authentication(config));
12 | };
13 |
--------------------------------------------------------------------------------
/test/services/table/index.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const assert = require('assert');
4 | const app = require('../../../src/app');
5 |
6 | describe('table service', function() {
7 | it('registered the tables service', () => {
8 | assert.ok(app.service('tables'));
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/test/services/user/index.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const assert = require('assert');
4 | const app = require('../../../src/app');
5 |
6 | describe('user service', function() {
7 | it('registered the users service', () => {
8 | assert.ok(app.service('users'));
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/public/tables.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Log In
15 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/services/user/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const NeDB = require('nedb');
5 | const service = require('feathers-nedb');
6 | const hooks = require('./hooks');
7 |
8 | module.exports = function(){
9 | const app = this;
10 |
11 | const db = new NeDB({
12 | filename: path.join(app.get('nedb'), 'users.db'),
13 | autoload: true
14 | });
15 |
16 | let options = {
17 | Model: db,
18 | paginate: {
19 | default: 5,
20 | max: 25
21 | }
22 | };
23 |
24 | // Initialize our service with any options it requires
25 | app.use('/users', service(options));
26 |
27 | // Get our initialize service to that we can bind hooks
28 | const userService = app.service('/users');
29 |
30 | // Set up our before hooks
31 | userService.before(hooks.before);
32 |
33 | // Set up our after hooks
34 | userService.after(hooks.after);
35 | };
36 |
--------------------------------------------------------------------------------
/src/services/table/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const NeDB = require('nedb');
5 | const service = require('feathers-nedb');
6 | const hooks = require('./hooks');
7 |
8 | module.exports = function(){
9 | const app = this;
10 |
11 | const db = new NeDB({
12 | filename: path.join(app.get('nedb'), 'tables.db'),
13 | autoload: true
14 | });
15 |
16 | let options = {
17 | Model: db,
18 | paginate: {
19 | default: 5,
20 | max: 25
21 | }
22 | };
23 |
24 | // Initialize our service with any options it requires
25 | app.use('/tables', service(options));
26 |
27 | // Get our initialize service to that we can bind hooks
28 | const tableService = app.service('/tables');
29 |
30 | // Set up our before hooks
31 | tableService.before(hooks.before);
32 |
33 | // Set up our after hooks
34 | tableService.after(hooks.after);
35 | };
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
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 |
23 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const serveStatic = require('feathers').static;
5 | const favicon = require('serve-favicon');
6 | const compress = require('compression');
7 | const cors = require('cors');
8 | const feathers = require('feathers');
9 | const configuration = require('feathers-configuration');
10 | const hooks = require('feathers-hooks');
11 | const rest = require('feathers-rest');
12 | const bodyParser = require('body-parser');
13 | const socketio = require('feathers-socketio');
14 | const middleware = require('./middleware');
15 | const services = require('./services');
16 | const authentication = require('feathers-authentication');
17 |
18 |
19 | const app = feathers();
20 |
21 | app.configure(configuration(path.join(__dirname, '..')));
22 |
23 | app.use(compress())
24 | .options('*', cors())
25 | .use(cors())
26 | .use(favicon( path.join(app.get('public'), 'favicon.ico') ))
27 | .use('/', serveStatic( app.get('public') ))
28 | .use(bodyParser.json())
29 | .use(bodyParser.urlencoded({ extended: true }))
30 | .configure(hooks())
31 | .configure(rest())
32 | .configure(socketio())
33 | .configure(services)
34 | .configure(middleware);
35 |
36 | module.exports = app;
37 |
--------------------------------------------------------------------------------
/src/services/user/hooks/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const globalHooks = require('../../../hooks');
4 | const hooks = require('feathers-hooks');
5 | const auth = require('feathers-authentication').hooks;
6 |
7 | exports.before = {
8 | all: [],
9 | find: [
10 | auth.verifyToken(),
11 | auth.populateUser(),
12 | auth.restrictToAuthenticated()
13 | ],
14 | get: [
15 | auth.verifyToken(),
16 | auth.populateUser(),
17 | auth.restrictToAuthenticated(),
18 | auth.restrictToOwner({ ownerField: '_id' })
19 | ],
20 | create: [
21 | auth.hashPassword()
22 | ],
23 | update: [
24 | auth.verifyToken(),
25 | auth.populateUser(),
26 | auth.restrictToAuthenticated(),
27 | auth.restrictToOwner({ ownerField: '_id' })
28 | ],
29 | patch: [
30 | auth.verifyToken(),
31 | auth.populateUser(),
32 | auth.restrictToAuthenticated(),
33 | auth.restrictToOwner({ ownerField: '_id' })
34 | ],
35 | remove: [
36 | auth.verifyToken(),
37 | auth.populateUser(),
38 | auth.restrictToAuthenticated(),
39 | auth.restrictToOwner({ ownerField: '_id' })
40 | ]
41 | };
42 |
43 | exports.after = {
44 | all: [hooks.remove('password')],
45 | find: [],
46 | get: [],
47 | create: [],
48 | update: [],
49 | patch: [],
50 | remove: []
51 | };
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Poker
2 |
3 | > 2-player poker game
4 |
5 | ## About
6 |
7 | This project uses [Feathers](http://feathersjs.com). An open source web framework for building modern real-time applications.
8 |
9 | ## Getting Started
10 |
11 | Getting up and running is as easy as 1, 2, 3.
12 |
13 | 1. Make sure you have [NodeJS](https://nodejs.org/) and [npm](https://www.npmjs.com/) installed.
14 | 2. Install your dependencies
15 |
16 | ```
17 | cd path/to/Poker; npm install
18 | ```
19 |
20 | 3. Start your app
21 |
22 | ```
23 | npm start
24 | ```
25 |
26 | ## Testing
27 |
28 | Simply run `npm test` and all your tests in the `test/` directory will be run.
29 |
30 | ## Scaffolding
31 |
32 | Feathers has a powerful command line interface. Here are a few things it can do:
33 |
34 | ```
35 | $ npm install -g feathers-cli # Install Feathers CLI
36 |
37 | $ feathers generate service # Generate a new Service
38 | $ feathers generate hook # Generate a new Hook
39 | $ feathers generate model # Generate a new Model
40 | $ feathers help # Show all commands
41 | ```
42 |
43 | ## Help
44 |
45 | For more information on all the things you can do with Feathers visit [docs.feathersjs.com](http://docs.feathersjs.com).
46 |
47 | ## Changelog
48 |
49 | __0.1.0__
50 |
51 | - Initial release
52 |
53 | ## License
54 |
55 | Copyright (c) 2016
56 |
57 | Licensed under the [MIT license](LICENSE).
58 |
--------------------------------------------------------------------------------
/test/app.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const assert = require('assert');
4 | const request = require('request');
5 | const app = require('../src/app');
6 |
7 | describe('Feathers application tests', function() {
8 | before(function(done) {
9 | this.server = app.listen(3030);
10 | this.server.once('listening', () => done());
11 | });
12 |
13 | after(function(done) {
14 | this.server.close(done);
15 | });
16 |
17 | it('starts and shows the index page', function(done) {
18 | request('http://localhost:3030', function(err, res, body) {
19 | assert.ok(body.indexOf('') !== -1);
20 | done(err);
21 | });
22 | });
23 |
24 | describe('404', function() {
25 | it('shows a 404 HTML page', function(done) {
26 | request({
27 | url: 'http://localhost:3030/path/to/nowhere',
28 | headers: {
29 | 'Accept': 'text/html'
30 | }
31 | }, function(err, res, body) {
32 | assert.equal(res.statusCode, 404);
33 | assert.ok(body.indexOf('') !== -1);
34 | done(err);
35 | });
36 | });
37 |
38 | it('shows a 404 JSON error without stack trace', function(done) {
39 | request({
40 | url: 'http://localhost:3030/path/to/nowhere',
41 | json: true
42 | }, function(err, res, body) {
43 | assert.equal(res.statusCode, 404);
44 | assert.equal(body.code, 404);
45 | assert.equal(body.message, 'Page not found');
46 | assert.equal(body.name, 'NotFound');
47 | done(err);
48 | });
49 | });
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Poker",
3 | "description": "2-player poker game",
4 | "version": "0.0.0",
5 | "homepage": "",
6 | "main": "src/",
7 | "keywords": [
8 | "feathers"
9 | ],
10 | "license": "MIT",
11 | "repository": {},
12 | "author": {},
13 | "contributors": [],
14 | "bugs": {},
15 | "engines": {
16 | "node": ">= 0.12.0"
17 | },
18 | "scripts": {
19 | "test": "npm run jshint && npm run mocha",
20 | "jshint": "jshint src/. test/. --config",
21 | "start": "node src/",
22 | "mocha": "mocha test/ --recursive",
23 | "webpack": "./node_modules/.bin/webpack --watch"
24 | },
25 | "dependencies": {
26 | "babel-core": "^6.17.0",
27 | "babel-loader": "^6.2.5",
28 | "babel-preset-es2015": "^6.16.0",
29 | "babel-preset-react": "^6.16.0",
30 | "body-parser": "^1.15.2",
31 | "compression": "^1.6.2",
32 | "cors": "^2.8.1",
33 | "feathers": "^2.0.2",
34 | "feathers-authentication": "^0.7.11",
35 | "feathers-configuration": "^0.3.3",
36 | "feathers-errors": "^2.4.0",
37 | "feathers-hooks": "^1.5.8",
38 | "feathers-nedb": "^2.5.1",
39 | "feathers-rest": "^1.5.0",
40 | "feathers-socketio": "^1.4.1",
41 | "lodash": "^4.16.4",
42 | "nedb": "^1.8.0",
43 | "passport": "^0.3.2",
44 | "poker-evaluator": "^0.3.1",
45 | "react": "^15.3.2",
46 | "react-dom": "^15.3.2",
47 | "serve-favicon": "^2.3.0",
48 | "webpack": "^1.13.2",
49 | "winston": "^2.2.0"
50 | },
51 | "devDependencies": {
52 | "jshint": "^2.9.4",
53 | "mocha": "^3.1.2",
54 | "request": "^2.75.0"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------