Skip to content

Commit 4be82b0

Browse files
committed
Project Update
- Migrated Bootstrap to CDN, and removed static versions - Created a bit of a layout using Bootstrap that advertises and gives credit to the facilities used - Added finishing touches to user facilities - Added install folder with .sql file that developers can use to seed their database - Updated mmod.css to restyle the 404 from nk, and then I changed the name to nk-mvc.css - Updated all areas according to changes in nk and nk-mysql, too much to list at this point. - Updated README - Updated version Change-Id: I268bbad2c7eeab152cd1b6cc59e96185c5402af6 Signed-off-by: Richard Winters <rik@mmogp.com>
1 parent d8e8ac2 commit 4be82b0

31 files changed

+442
-8772
lines changed

LICENSE

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
MMOD-NODE is Copyright 2011-2014 Massively Modified, Inc. <support@mmogp.com>
1+
nodakwaeri, nodamysql, and nk-mvc are Copyright 2011-2014 Massively Modified, Inc. <support@mmogp.com>
22

33
Licensed under the Apache License, Version 2.0 (the "License");
44
you may not use this file except in compliance with the License.
@@ -10,4 +10,19 @@ Unless required by applicable law or agreed to in writing, software
1010
distributed under the License is distributed on an "AS IS" BASIS,
1111
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
See the License for the specific language governing permissions and
13-
limitations under the License.
13+
limitations under the License.
14+
15+
16+
MySQL Connector C++ is licensed under the FOSS License Exception, and is bound
17+
by the terms of the above Apache License (Version 2.0). A copy of the terms of
18+
the FOSS License Exception can be found via the link supplied within the License
19+
and Source of the accompanying MySQL Connector C++ Source, or by visiting the
20+
following link
21+
22+
http://www.mysql.com/about/legal/licensing/foss-exception/
23+
24+
25+
SJCL is licensed under a multi-clause BSD license. You may obtain a copy
26+
of the license at
27+
28+
http://github.com/bitwiseshiftleft/sjcl/blob/master/README/bsd.txt

README.md

+124-15
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,143 @@
1-
# nk-mvc
1+
# nk-mvc ( v0.1.0 )
22

3-
The 'Hello World!' example of a nodakwaeri MVC Application.
3+
The 'Hello World!' example of - and project template for - a nodakwaeri MVC Application.
44

5+
<b>Notice:</b>
6+
Please keep in mind that while the version is '0'.<anything> ( the key part being '0' in front ), this package should be considered - and used as if it were - a pre-release. Things should work, but you may find issues. I would encourage you to please report them [here](https://github.com/mmod/nk-mvc/issues).
57

6-
##Installation
78

8-
To get started, open terminal/shell/command prompt and browse to the root of your application. Clone the nk-mvc repository:
9+
## Downloading
10+
11+
To get started, open terminal/shell/command prompt and browse to the root of where you'll store your application. Clone the nk-mvc repository:
912

1013
```
11-
path_to_application/> git clone git@github.com/mmod/nk-mvc.git
14+
path_to_application_root/> git clone git@github.com/mmod/nk-mvc.git
1215
```
1316

14-
When finished we need to install the dependencies. Unless I'm wrong:
17+
Alternatively, you could just download a [zip of the source](https://github.com/mmod/nk-mvc/archive/master.zip) and extract it to where you wish to keep the application.
18+
19+
When finished we need to install the dependencies but before we do that we need to make sure we have some prerequisites in place.
20+
21+
22+
## Required Prerequisites
23+
24+
Whether you wish to build or not build any of the components, the [nk-mysql documentation](http://github.com/mmod/nk-mysql) will guide you in ensuring you meet any and all requirements. Once you've gone through the respective documentation, a link is provided which will redirect you back here in order to complete installation.
25+
26+
27+
## The actual installation
28+
29+
Since we already have nk-mvc, all we need to do is install the dependencies for it and we'll be good to go. Assuming we've ensured we meet all of the prerequisites/requirements...
1530

1631
```
17-
path_to_application/> npm install .
32+
path_to_nk-mvc-application/> npm install .
1833
```
1934

20-
Should do the trick, but in case it doesn't:
35+
...will do the trick.
2136

37+
38+
## Configuration
39+
40+
### Seed the Database
41+
42+
In the root of your nk-mvc application, you'll find a directory named <i>install</i> containing a file named <i>seed.sql</i>. If you open the file you will see in 2 places exists the string: <b><ReplaceWithAHashedPassword></b>. You will need to replace these with - you guessed it - a hashed password.
43+
44+
In order to do this, create a file <i>whatever.js</i> in the root of your application, and add the following code to it (replacing <YourPasswordHere> and <YourSecretHere>) with your actual password and secret, respectively:
45+
46+
```node
47+
var nk = require( 'nk' ),
48+
nk = new nk(),
49+
pass = "<YourPasswordHere>",
50+
secret = "<YourSecretHere>";
51+
52+
console.log( nk.hash( { data: pass, salt: key } );
2253
```
23-
path_to_application/> npm install nk;
24-
path_to_application/> npm install nodamysql;
25-
```
54+
55+
56+
Please note, that the secret can be a 10 character or 100 character string; nodakwaeri will use it to generate a 256-bit salt. You will want to remember the string you used for the secret so as you build your user system out you have it to generate the hash again for comparison during login.
57+
58+
Save the file and execute it using node.js:
59+
60+
```node
61+
path_to_nk-mvc_application/>node whatever.js
62+
```
63+
64+
Alternatively, you could just throw the console.log bit into the index.js file and start your server...either way:
65+
66+
The hash function let's you supply a secret that it then hashes; so that you can supply it either with the same string over and over, or by invoking a function that will return a secret from elsewhere, since - being realistic - the more acceptable and professionally practiced way to build a <i>secure</i> authentication system is to store secrets and/or encrypt passwords on an external device; but we're not going to do that just to play around are we?
67+
68+
Take the hashed password printed on your console window / terminal as a result of the console.log (wherever it came from), and add it to the .sql file - replacing the existing <ReplaceWithHashedPassword> values where they are.
69+
70+
BTW, I really don't mind if you want to pretend to be me, but you could go ahead and change the other identifying info in the .sql file as well - like the username, name, etc. And unless you want to have to make modifications to the account controller and model, and don't care to even run the example, I'd suggest you only change database names, database user names, and database passwords; leaving the table names and columns as they are until you're ready to start developing.
71+
72+
Run/Execute the contents of the .sql file either in MySQL Workbench, or via your favorite means (in the future nk-mysql will have additional tools which will provide features similar to Microsoft's Migrations, but until then...)
73+
74+
### Configure the Application
75+
76+
To finish configuring your application, open the config.js file in the root of your nk-mvc application. In this file, notice the URL and SERVER members of both the development and production configuration schemas; You probably need to update at least one of them, as well as any mail config (though we can't use it yet, its there to remind me to build that in!). If you're developing locally and not using a host entry (meaning you're typing localhost into your browser), then the URL <i>should</i> be http://localhost:XXXX 'lest you want problems.
77+
78+
The only other changes you may need to make, are in the database sections of the configuration file.
79+
80+
You're all configured now, moving on.
81+
2682
2783
## Usage
2884
29-
At this time, all examples can be found within the app/ directory of the source.
85+
To use your new nk-mvc application:
86+
87+
#### On Windows:
88+
89+
```node
90+
path_to_nk-mvc_application/>set NODE_ENV=development
91+
path_to_nk-mvc_application/>node index.js
92+
```
93+
94+
#### On Linux/Unix:
95+
96+
```node
97+
path_to_nk-mvc_application/>NODE_ENV=development node index.js
98+
```
99+
100+
101+
Some console output should have alerted you that the application is running. Try visiting http://localhost:7724 if you did not make any changes to the configuration...otherwise I'm guessing you know what you're doing :)
102+
103+
104+
## Developing with nk-mvc
105+
106+
<i>At this time, all examples can be found within the app/ directory of the source.</i>
107+
108+
### The Gist
109+
110+
Like any MVC Framework, it's up to the developers to supply the Controllers, Models, and Views which make up the application.
111+
112+
#### Controllers
113+
114+
Controllers are where we set/get session variables, they're where we invoke data queries, and they are where we place most application or business logic specific to our application.
115+
116+
Properties of a controller object are considered the different 'actions' the controller provides to the application; simply adding a new action to an existing controller will yield a new usable URL: domain/<controller>/<action>. Adding 'Post' to the end of a controller action name will let the framework know that it should be called when a POST is made upon that URL.
117+
118+
Take a look at the account.js file in the /app/controllers/ directory to see some examples.
119+
120+
121+
<i>Currently there are no examples for API transactions, however -> responding to API requests will take place directly in the controller. Example coming soon.</i>
122+
123+
#### Models
124+
125+
Models are where we define data queries, and data properties.
126+
127+
Members of a model file's object are considered 'models'; You could essentially have numerous related models within a single model file. From within a model, we are able to access the database object, and are typically fed a callback to make data processing implicitly asynchronous.
128+
129+
Take a look at the account.js file in the /app/models/ directory to see an example.
130+
131+
#### Views
132+
133+
Views are where we define what the end user is going to see when the response is set (and we are returning a content type of text/html). This involves preparation of a layout as well as content for the layout.
134+
135+
Each directory under /app/views (aside from shared), denotes a set of views for each controller's various actions. The _shared directory under /app/views allows developers to create 'layouts' or 'templates' which are available to the entire application.
136+
137+
Take a look at the various files within the /app/views/ directory to see some examples.
138+
139+
<b>A little note</b>
140+
<i>To change your favicon, just replace the favicon.ico that exists in the assets/ directory. Icons cache in Windows, so after dropping your new favicon you may notice that in file explorer the old icon is still displaying (yea, until you restart). Rest assured that once you've deleted your browsers cache, in the browser the proper favicon will show (even before restarting).</i>
30141
31142
32143
## Development
@@ -36,11 +147,9 @@ Feel free to fork the repository and submit pull requests. As the framework dev
36147
37148
### Created with:
38149
39-
[Eclipse Kepler](https://www.eclipse.org/downloads/)
150+
[Eclipse Luna](https://www.eclipse.org/downloads/)
40151
41152
[Nodeclipse](https://github.com/Nodeclipse/nodeclipse-1)
42153
([Eclipse Marketplace](http://marketplace.eclipse.org/content/nodeclipse), [site](http://www.nodeclipse.org))
43154
44155
[Node.js](http://nodejs.org)
45-
46-
The above software(s) are all free, open-source projects which grow with each new contribution.

app/controllers/account.js

+60-36
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/**
2-
* account.js
3-
*
4-
* package: MMod-Node
5-
* version: $id$
6-
* author: Richard B. Winters <a href="mailto:rik@massivelymodified.com">rik At MassivelyModified</a>
2+
* package: nk-mvc
3+
* sub-package: controllers/account
4+
* author: Richard B. Winters <a href="mailto:rik@mmogp.com">rik At Massively Modified</a>
75
* copyright: 2013-2014 Massively Modified, Inc.
6+
* license: Apache, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0>
87
*/
98

109
module.exports = exports = accountController;
@@ -15,6 +14,11 @@ function accountController()
1514

1615
accountController.prototype.index = function( request, response )
1716
{
17+
// Undoubtedly there will be session variables we will want to keep persistent.
18+
response.session.set( 'username', request.session.get( 'username', 'Guest' ), { secure: true } );
19+
response.session.set( 'email', request.session.get( 'email', '' ), { secure: true } );
20+
response.session.set( 'name', JSON.stringify( JSON.parse( request.session.get( 'name', JSON.stringify( { first: 'Guest' } ) ) ) ), { secure: true } );
21+
1822
var layout = this.config.view_provider;
1923

2024
// We just need to display fields for a login here
@@ -24,7 +28,8 @@ accountController.prototype.index = function( request, response )
2428
layout: 'shared/main',
2529
viewbag: {
2630
title: 'MMOD Framework',
27-
pagetitle: 'Nothing to see here...'
31+
pagetitle: 'Nothing to see here...',
32+
username: request.session.get( 'username', 'Guest' )
2833
}
2934
};
3035

@@ -34,14 +39,13 @@ accountController.prototype.index = function( request, response )
3439
// HTTP GET /account/login
3540
accountController.prototype.login = function( request, response )
3641
{
42+
// Undoubtedly there will be session variables we will want to keep persistent.
43+
response.session.set( 'username', request.session.get( 'username', 'Guest' ), { secure: true } );
44+
response.session.set( 'email', request.session.get( 'email', '' ), { secure: true } );
45+
response.session.set( 'name', JSON.stringify( JSON.parse( request.session.get( 'name', JSON.stringify( { first: 'Guest' } ) ) ) ), { secure: true } );
46+
3747
var layout = this.config.view_provider;
3848

39-
for( var part in request.requrl.query )
40-
{
41-
console.log( 'Get Var: `' + part + '`, Value: `' + request.requrl.query[part] + '`.' );
42-
}
43-
// declare model here, prepare it however it is required to be prepared, and add it to the klay object
44-
4549
// We just need to display fields for a login here
4650
var klay = {
4751
controller: this.config.controller,
@@ -50,7 +54,8 @@ accountController.prototype.login = function( request, response )
5054
layout: 'shared/main',
5155
viewbag: {
5256
title: 'MMOD Framework',
53-
pagetitle: 'Please log in'
57+
pagetitle: 'Please log in',
58+
username: request.session.get( 'username', 'Guest' )
5459
}
5560
};
5661

@@ -60,8 +65,13 @@ accountController.prototype.login = function( request, response )
6065
// HTTP POST /account/login
6166
accountController.prototype.loginPost = function( request, response )
6267
{
68+
var na = this;
69+
70+
// Here we're going to want to use our database provider, when we do so we'll define a callback to send along with our query
71+
// to support an implicit asynchronicity.
6372
var viewModel = require( '../models/account' ).loginView,
64-
model = this.model.set( viewModel ),
73+
loginModel = require( '../models/account' ).login,
74+
model = this.model.set( loginModel ),
6575
layout = this.config.view_provider,
6676
klay = {
6777
controller: this.config.controller,
@@ -70,44 +80,52 @@ accountController.prototype.loginPost = function( request, response )
7080
layout: 'shared/main',
7181
viewbag: {
7282
title: 'MMOD Framework',
73-
pagetitle: 'You tried to log in.'
83+
pagetitle: 'You tried to log in.',
84+
username: request.session.get( 'username' )
7485
}
7586
};
7687

77-
// Here we define a callback for our authentication method
78-
var callback = function( req, res, authenticated )
88+
// Here we define the callback for our authentication method
89+
var callback = function( req, res, authenticated, tk )
7990
{
80-
if( authenticated !== false )
91+
if( !authenticated )
8192
{
82-
req.session.data.isAuthenticated = true;
83-
if( request.posted.rememberme !== undefined || null || false )
84-
{
85-
request.session.data.persistence = true;
86-
}
87-
req.session.data.username = req.posted.username;
88-
req.session.data.password = req.posted.password;
89-
req.session.data.email = authenticated.email;
90-
req.session.data.name.first = authenticated.first;
91-
req.session.data.name.last = authenticated.last;
93+
res.session.set( 'name', { first: 'Guest' }, { secure: true } );
94+
res.session.set( 'username', 'Guest', { secure: true } );
95+
96+
layout.turn( req, res, tk );
9297
}
9398
else
9499
{
95-
req.session.data.isAuthenticated = false;
96-
req.session.data.name.first = 'Guest';
100+
// Using POST variables is quite easy as well:
101+
if( req.posted.rememberme )
102+
{
103+
res.session.set( 'persistence', true, { secure: true } );
104+
}
105+
106+
res.session.set( 'username', authenticated[0].username, { secure: true } );
107+
res.session.set( 'email', authenticated[0].email, { secure: true } );
108+
res.session.set( 'name', JSON.stringify( { first: authenticated[0].first, last: authenticated[0].last } ), { secure: true } );
109+
110+
// Let's redirect, but remember to set the session before we do.
111+
res.redirect( '/' );
97112
}
98-
99-
layout.turn( req, res, klay );
100113
};
101114

102-
// And here we asynchronously execute the model's authenticate method. I'm sure you can see the changes you would need to make
115+
// And here we invoke the model's authenticate method. I'm sure you can see the changes you would need to make
103116
// in this controller method to make things synchronous instead (i.e. remove code body from callback, have it run after model executes, but have
104117
// model return its value to a variable within this method's scope like var authenticated = mode.authenticate... callback can be left undefined.)
105-
model.authenticate( request, response, callback );
118+
model.authenticate( request, response, callback, klay );
106119
};
107120

108121
// HTTP /account/manage
109122
accountController.prototype.manage = function( request, response )
110123
{
124+
// Undoubtedly there will be session variables we will want to keep persistent.
125+
response.session.set( 'username', request.session.get( 'username', 'Guest' ), { secure: true } );
126+
response.session.set( 'email', request.session.get( 'email', '' ), { secure: true } );
127+
response.session.set( 'name', JSON.stringify( JSON.parse( request.session.get( 'name', JSON.stringify( { first: 'Guest' } ) ) ) ), { secure: true } );
128+
111129
var viewModel = require( '../models/account' ).manageView,
112130
layout = this.config.view_provider,
113131
klay = {
@@ -119,7 +137,7 @@ accountController.prototype.manage = function( request, response )
119137
title: 'MMOD Framework',
120138
pagetitle: 'Please manage yourself.',
121139
usercompany: 'Massively Modified, Inc.',
122-
username: 'Rik',
140+
username: request.session.get( 'username', 'Guest' ),
123141
useremail: 'rik@mmogp.com',
124142
usertypes: { 'a': 'Guest', 'b': 'Registered', 'c': 'Moderator', 'd': 'Administrator' }
125143
}
@@ -131,6 +149,11 @@ accountController.prototype.manage = function( request, response )
131149
//HTTP POST /account/manage
132150
accountController.prototype.managePost = function( request, response )
133151
{
152+
// Undoubtedly there will be session variables we will want to keep persistent.
153+
response.session.set( 'username', request.session.get( 'username', 'Guest' ), { secure: true } );
154+
response.session.set( 'email', request.session.get( 'email', '' ), { secure: true } );
155+
response.session.set( 'name', JSON.stringify( JSON.parse( request.session.get( 'name', JSON.stringify( { first: 'Guest' } ) ) ) ), { secure: true } );
156+
134157
var layout = this.config.view_provider;
135158

136159
// We just need to display fields for a login here
@@ -139,7 +162,8 @@ accountController.prototype.managePost = function( request, response )
139162
view: this.config.view,
140163
layout: 'shared/main',
141164
title: 'MMOD Framework',
142-
pagetitle: 'Please manage yourself'
165+
pagetitle: 'Please manage yourself',
166+
username: request.session.get( 'username', 'Guest' )
143167
};
144168

145169
layout.turn( request, response, klay );

0 commit comments

Comments
 (0)