Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.7.0 beta #36

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Webistor API - Version 0.6.1 Beta
# Webistor API - Version 0.7.0 Beta

## Installing (Linux Debian)

Expand Down
2 changes: 1 addition & 1 deletion bin/import
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ migrate = (database) ->
##

# Connect to the mongoose database.
mongoose.connect config.database
mongoose.connect "mongodb://#{config.database.host}/#{config.database.name}"

# Go!
program.parse process.argv
2 changes: 1 addition & 1 deletion bin/invite
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ invite = (options = {}) ->
##

# Connect to the database.
mongoose.connect config.database
mongoose.connect "mongodb://#{config.database.host}/#{config.database.name}"

# Go!
program.parse process.argv
2 changes: 1 addition & 1 deletion bin/shutdown
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ log = require 'node-logging'
# Request options.
options =
host: "localhost"
port: config.daemon.adminPort
port: config.proxy.adminPort
path: "/shutdown"

# Create request.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webistor-api",
"version": "0.6.1-beta",
"version": "0.7.0-beta",
"description": "Webistor server API",
"main": "lib/index.js",
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions src/classes/auth.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ module.exports = class Auth
return Promise.reject new AuthError AuthError.EXPIRED, "Auth instance expired." if @isExpired()
return Promise.reject new AuthError AuthError.LOCKED, "Auth instance locked." if @isLocked()
@token = randtoken.generate 32
Promise.resolve @token

###*
* Determine if this authentication session is locked for any reason.
Expand Down
69 changes: 69 additions & 0 deletions src/client.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
express = require 'express'
serveStatic = require 'serve-static'
staticFavicon = require 'static-favicon'

###*
* Creates a new client, static file host.
* @param {object} config Dependency injection of the configuration values.
* See `/config.coffee`.
* @param {object} opts Holds the options for this client.
* - html: the location of local files to serve.
* - port: (optional) the port to listen on directly.
* @return {Express} The created client express instance.
###
module.exports = (config, opts) ->

# Favicon middleware.
favicon = staticFavicon "#{opts.html}/icons/favicon.ico"

# Instantiate client application-server.
client = express()

# Content Security Policy.
client.use (req, res, next) ->

# Arrays of whitelisted domains for styles and fonts.
styleDomains = ['fonts.googleapis.com', 'netdna.bootstrapcdn.com']
fontDomains = ['themes.googleusercontent.com', 'netdna.bootstrapcdn.com', 'fonts.gstatic.com']

# Chrome implemented CSP properly.
if /Chrome/.test req.headers['user-agent']
styles = styleDomains.join(' ')
fonts = fontDomains.join(' ')

# Others didn't.
else
styles =
styleDomains.map((domain) -> "http://#{domain}").join(' ') + ' ' +
styleDomains.map((domain) -> "https://#{domain}").join(' ')
fonts =
fontDomains.map((domain) -> "http://#{domain}").join(' ') + ' ' +
fontDomains.map((domain) -> "https://#{domain}").join(' ')

# Send the CSP header.
res.header 'Content-Security-Policy', [
"default-src 'none'"
"style-src 'self' 'unsafe-inline' " + styles
"font-src 'self' " + fonts
"script-src 'self' 'unsafe-eval'"
"img-src 'self'"
"connect-src api.#{config.domainName}" + (
if config.debug then " ws://localhost:9485/ localhost:#{config.serverPort}" else ''
)
].join(';\n')

# Next middleware.
next()

# Set up shared middleware.
client.use favicon

# Set up routing to serve up static files from the /public folder, or index.html.
client.use serveStatic opts.html
client.get '*', (req, res) -> res.sendFile "#{opts.html}/index.html"

# Start listening on the client port, if any.
client.listen opts.port if opts.port

# Return the express instance.
return client
20 changes: 13 additions & 7 deletions src/config.coffee
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
module.exports =
debug: false
logLevel: ['debug', 'info', 'error'][1]

domainName: 'webistor.net'
timezone: 'Europe/Amsterdam'
clientPort: null
serverPort: null
debug: false
logLevel: ['debug', 'info', 'error'][0]
timezone: 'Europe/Amsterdam'
publicHtml: '/absolute/path/to/public'
whitelist: ['localhost', 'webistor.net', 'www.webistor.net']

stableHtml: '/home/node/webistor/app-stable/public/'
newHtml: '/home/node/webistor/app-new/public/'

# For Content Security Policy
whitelist: ['localhost', 'webistor.net', 'www.webistor.net', 'new.webistor.net']

# Database settings.
database:
Expand Down Expand Up @@ -34,8 +39,9 @@ module.exports =
# An array of usernames which users are not allowed to take.
reservedUserNames: ['me']

# Daemon settings.
daemon:
# Proxy settings.
proxy:
redirectToHttps: true
enabled: true
httpPort: 80
adminPort: 3002
Expand Down
29 changes: 29 additions & 0 deletions src/controllers/feedback-controller.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Controller = require './base/controller'
Promise = require 'bluebird'
ServerError = require './base/server-error'
config = require '../config'
log = require 'node-logging'
Mail = require '../classes/mail'

module.exports = class FeedbackController extends Controller

###*
* Send user feedback to [email protected].
*
* @param {http.IncomingMessage} req The Express request object. Required fields:
* `req.body.subject`: The feedback subject line.
*
* @return {Promise} A Promise which resolves once the response is generated.
###
contribution: (req, res) ->

# Ensure a subject was given.
throw new ServerError 400, "No subject given." unless req.body.subject

# Send an email to [email protected].
return new Mail()
.from req.body.email
.to "[email protected]"
.subject "Webistor Feedback - #{req.body.subject}"
.template "feedback/contribution", {req}
.send()
18 changes: 9 additions & 9 deletions src/controllers/session-controller.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -384,15 +384,15 @@ module.exports = class SessionController extends Controller
auth = @passwordTokenAuth[user.id] or= @authFactory.create user, => delete @passwordTokenAuth[user.id]

# Generate a token with which they can reset their password.
token = auth.generateToken()

# Send them the token.
(new Mail)
.to user
.from "Webistor Team <[email protected]>"
.subject "Your password reset ticket"
.template "account/password-token", {user, token}
.send()
auth.generateToken().then (token) ->
# Send them the token.
(new Mail)
.to user
.from "Webistor Team <[email protected]>"
.subject "Your password reset ticket"
.template "account/password-token", {user, token}
.send()

# Done.
.return "Mail sent."
Expand Down
Loading