-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathserver.js
163 lines (126 loc) · 4.62 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* jshint node: true */
'use strict';
var express = require( 'express' ),
bodyParser = require( 'body-parser' ),
sessions = require( 'client-sessions' ),
app = express(),
_getAudio,
_getImage,
_startRoute,
_trySubmission;
// Set session information
app.use( sessions({
cookieName: 'session',
secret: 'someRandomSecret!',
duration: 24 * 60 * 60 * 1000,
activeDuration: 1000 * 60 * 5
}) );
// Enable CORS
app.use( function( req, res, next ) {
res.header( 'Access-Control-Allow-Origin', '*' );
next();
} );
// parse application/x-www-form-urlencoded
app.use( bodyParser.urlencoded({ extended: false }) );
// parse application/json
app.use( bodyParser.json() );
// Set public path
app.use( express.static( __dirname + '/public' ) );
// Define routes functions
// Fetches and streams an audio file
_getAudio = function( req, res, next ) {
var visualCaptcha;
// Default file type is mp3, but we need to support ogg as well
if ( req.params.type !== 'ogg' ) {
req.params.type = 'mp3';
}
// Initialize visualCaptcha
visualCaptcha = require( 'visualcaptcha' )( req.session, req.query.namespace );
visualCaptcha.streamAudio( res, req.params.type );
};
// Fetches and streams an image file
_getImage = function( req, res, next ) {
var visualCaptcha,
isRetina = false;
// Initialize visualCaptcha
visualCaptcha = require( 'visualcaptcha' )( req.session, req.query.namespace );
// Default is non-retina
if ( req.query.retina ) {
isRetina = true;
}
visualCaptcha.streamImage( req.params.index, res, isRetina );
};
// Start and refresh captcha options
_startRoute = function( req, res, next ) {
var visualCaptcha;
// Initialize visualCaptcha
visualCaptcha = require( 'visualcaptcha' )( req.session, req.query.namespace );
visualCaptcha.generate( req.params.howmany );
// We have to send the frontend data to use on POST.
res.status( 200 ).send( visualCaptcha.getFrontendData() );
};
// Try to validate the captcha
// We need to make sure we generate new options after trying to validate, to avoid abuse
_trySubmission = function( req, res, next ) {
var visualCaptcha,
namespace = req.query.namespace,
frontendData,
queryParams = [],
imageAnswer,
audioAnswer,
responseStatus,
responseObject;
// Initialize visualCaptcha
visualCaptcha = require( 'visualcaptcha' )( req.session, req.query.namespace );
frontendData = visualCaptcha.getFrontendData();
// Add namespace to query params, if present
if ( namespace && namespace.length !== 0 ) {
queryParams.push( 'namespace=' + namespace );
}
// It's not impossible this method is called before visualCaptcha is initialized, so we have to send a 404
if ( typeof frontendData === 'undefined' ) {
queryParams.push( 'status=noCaptcha' );
responseStatus = 404;
responseObject = 'Not Found';
} else {
// If an image field name was submitted, try to validate it
if ( ( imageAnswer = req.body[ frontendData.imageFieldName ] ) ) {
if ( visualCaptcha.validateImage( imageAnswer ) ) {
queryParams.push( 'status=validImage' );
responseStatus = 200;
} else {
queryParams.push( 'status=failedImage' );
responseStatus = 403;
}
} else if ( ( audioAnswer = req.body[ frontendData.audioFieldName ] ) ) {
// We set lowercase to allow case-insensitivity, but it's actually optional
if ( visualCaptcha.validateAudio( audioAnswer.toLowerCase() ) ) {
queryParams.push( 'status=validAudio' );
responseStatus = 200;
} else {
queryParams.push( 'status=failedAudio' );
responseStatus = 403;
}
} else {
queryParams.push( 'status=failedPost' );
responseStatus = 500;
}
}
if ( req.accepts( 'html' ) !== undefined ) {
res.redirect( '/?' + queryParams.join( '&' ) );
} else {
res.status( responseStatus );
}
};
// Routes definition
app.post( '/try', _trySubmission );
// @param type is optional and defaults to 'mp3', but can also be 'ogg'
app.get( '/audio', _getAudio );
app.get( '/audio/:type', _getAudio );
// @param index is required, the index of the image you wish to get
app.get( '/image/:index', _getImage );
// @param howmany is required, the number of images to generate
app.get( '/start/:howmany', _startRoute );
module.exports = app;
// API Listening Port
app.listen( process.env.PORT || 8282 );