snapporder: register_url works, started register.php
This commit is contained in:
1 parent
b36dc43339
commit
01bff75cd2
11 files changed
+264
-3
No files matched your search
@@ -2,6 +2,7 @@ credentials.php
|
|||||||
inside/tmp
|
inside/tmp
|
||||||
inside/migration/config.php
|
inside/migration/config.php
|
||||||
snapporder/config.php
|
snapporder/config.php
|
||||||
|
snapporder/node_modules
|
||||||
migration.log
|
migration.log
|
||||||
error_log
|
error_log
|
||||||
*.swp
|
*.swp
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
module.exports = function(grunt) {
|
||||||
|
grunt.initConfig({
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
|
||||||
|
autoprefixer: {
|
||||||
|
dist: {
|
||||||
|
files: {
|
||||||
|
'css/style.css': 'css/style.css',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sass: {
|
||||||
|
options: {
|
||||||
|
includePaths: ['bower_components/foundation/scss']
|
||||||
|
},
|
||||||
|
dist: {
|
||||||
|
options: {
|
||||||
|
outputStyle: 'compressed'
|
||||||
|
//outputStyle: 'compact'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
'css/style.css': 'scss/style.scss'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
sass: {
|
||||||
|
files: ['scss/**/*.scss'],
|
||||||
|
tasks: ['sass', 'autoprefixer'],
|
||||||
|
},
|
||||||
|
livereload: {
|
||||||
|
files: ['**/*.php', 'css/style.css', '**/*.js'],
|
||||||
|
options: {
|
||||||
|
livereload: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// load all grunt tasks
|
||||||
|
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
|
||||||
|
|
||||||
|
grunt.registerTask('build', ['sass']);
|
||||||
|
grunt.registerTask('default', ['build','watch']);
|
||||||
|
};
|
||||||
+95
-1
@@ -3,9 +3,103 @@
|
|||||||
* SnappOrder first saves initial data in our temp user db
|
* SnappOrder first saves initial data in our temp user db
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - Present user form
|
|
||||||
* - validate user data
|
* - validate user data
|
||||||
* - load inside user object and populate it
|
* - load inside user object and populate it
|
||||||
* - persist to db
|
* - persist to db
|
||||||
*/
|
*/
|
||||||
|
set_include_path("../includes/");
|
||||||
|
|
||||||
|
require_once("../inside/credentials.php");
|
||||||
|
require_once("../inside/functions.php");
|
||||||
|
require_once("../includes/DB.php");
|
||||||
|
|
||||||
|
require_once("lib/functions.php");
|
||||||
|
require_once("config.php");
|
||||||
|
|
||||||
|
if( !isset($_GET['userid']) || !isset($_GET['token']) ) {
|
||||||
|
echo "Ugyldig aktiveringslenke. Ta kontakt med medlemskap@studentersamfundet.no hvis du har spørsmål.";
|
||||||
|
set_response_code(400);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to database */
|
||||||
|
$options = array( 'debug' => 2, 'portability' => DB_PORTABILITY_ALL );
|
||||||
|
$conn = DB::connect(getDSN(), $options);
|
||||||
|
if(DB :: isError($conn)) {
|
||||||
|
echo $conn->toString();
|
||||||
|
set_response_code(500);
|
||||||
|
echo 'Could not connect to DB';
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
$conn->setFetchMode(DB_FETCHMODE_ASSOC);
|
||||||
|
/* Fetch user and check for valid token */
|
||||||
|
$user = get_user($_GET['userid']);
|
||||||
|
if( !check_token($user, $_GET['token'], SECRET_KEY)) {
|
||||||
|
echo "Ugyldig aktiveringslenke. Ta kontakt med medlemskap@studentersamfundet.no hvis du har spørsmål.";
|
||||||
|
set_response_code(400);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isset($_POST['submit']) ) {
|
||||||
|
// TODO validate and persist
|
||||||
|
var_dump($_POST);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="no-js" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title></title>
|
||||||
|
<link rel="stylesheet" type="text/css" media="all" href="css/style.css" />
|
||||||
|
|
||||||
|
<!--<script src="js/jquery-1.11.0.js"></script>
|
||||||
|
<script src="bower_components/foundation/js/foundation.js"></script>
|
||||||
|
<script src="js/app.js"></script>-->
|
||||||
|
|
||||||
|
<!-- GA? -->
|
||||||
|
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title">Aktiver medlemskapet ditt</h1>
|
||||||
|
<header class="about">
|
||||||
|
<p>Hei <strong><?php echo $user['firstname']; ?></strong>, du er veldig nære å kunne:</p>
|
||||||
|
<ul class="incentives">
|
||||||
|
<li>Bruke trådløsnett på Chateau Neuf</li>
|
||||||
|
<li>Bli aktiv på Studentersamfundet</li>
|
||||||
|
</ul>
|
||||||
|
<h2>Din profil</h2>
|
||||||
|
<ul class="profile">
|
||||||
|
<?php
|
||||||
|
$visible_vars = array("firstname", "lastname", "email", "memberid");
|
||||||
|
foreach($user as $key=>$val) {
|
||||||
|
if( in_array($key, $visible_vars) ) {
|
||||||
|
echo "<li><strong>".ucfirst($key)."</strong>: $val</li>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul>
|
||||||
|
</header>
|
||||||
|
<section class="activation">
|
||||||
|
<h2>Kontodetaljer</h2>
|
||||||
|
<form method="post" class="activation-form">
|
||||||
|
<label for="id_username">Brukernavn:</label><input id="id_username" type="text" name="username" placeholder="Brukernavn"/>
|
||||||
|
<label for="id_password">Passord:</label><input id="id_password" type="password" name="password" placeholder="Passord"/>
|
||||||
|
<label for="id_date_of_birth">Fødselsdato:</label><input id="id_date_of_birth" type="text" name="date_of_birth" placeholder="Fødselsdato"/>
|
||||||
|
<label for="id_place_of_study">Studiested:</label><input id="id_place_of_study" type="text" name="place_of_study" placeholder="Studiested"/>
|
||||||
|
<button type="submit" name="submit" class="btn-submit">Aktiver medlemskapet</button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
<footer>
|
||||||
|
<img src="https://brukerinfo.neuf.no/static/style/img/DNSlogo.png">
|
||||||
|
<img src="http://www.snapporder.com/img/snapporder_logo_dark_liggende.png">
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -72,6 +72,11 @@ $user = get_user($user_id);
|
|||||||
/* Add back phone number from query */
|
/* Add back phone number from query */
|
||||||
$user['phone'] = $phone;
|
$user['phone'] = $phone;
|
||||||
|
|
||||||
|
/* Add register url if needed */
|
||||||
|
if($user['registration_status'] === "partial") {
|
||||||
|
$user['registation_url'] = generate_registration_url($user, SECRET_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return encrypted user object */
|
/* Return encrypted user object */
|
||||||
echo json_encode($user);
|
echo json_encode($user);
|
||||||
//echo $crypt->encrypt(json_encode($user));
|
//echo $crypt->encrypt(json_encode($user));
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
* "register_url": "/snapporder/register_partial.php?id=4331&hmac=lol"
|
* "register_url": "/snapporder/register_partial.php?id=4331&hmac=lol"
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* TODO register url
|
|
||||||
* TODO Add entry in din_userupdate
|
* TODO Add entry in din_userupdate
|
||||||
* TODO maybe check $_SERVER['REQUEST_METHOD']
|
* TODO maybe check $_SERVER['REQUEST_METHOD']
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "inside-snapporder",
|
||||||
|
"dependencies": {
|
||||||
|
"foundation": "zurb/bower-foundation",
|
||||||
|
"underscore": "latest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
define("SNAP_IV", 'kdj87wncboq20jcv');
|
define("SNAP_IV", 'kdj87wncboq20jcv');
|
||||||
define("SNAP_KEY", 'lkdowdjf82736esc');
|
define("SNAP_KEY", 'lkdowdjf82736esc');
|
||||||
|
define("SECRET_KEY", 'ahtoufahsohpieVah9iegahzeiteijei9Aengu1veeSh8iviengaen4ooZeeThe2');
|
||||||
|
define("REGISTRATION_URL_TIMEOUT_DAYS", 3);
|
||||||
?>
|
?>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,progress,video{display:inline-block;vertical-align:baseline;}audio:not([controls]){display:none;height:0;}[hidden],template{display:none;}a{background:transparent;}a:active,a:hover{outline:0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}h1{font-size:2em;margin:0.67em 0;}mark{background:#ff0;color:#000;}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:1em 40px;}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0;}pre{overflow:auto;}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em;}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0;}button{overflow:visible;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}input{line-height:normal;}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}textarea{overflow:auto;}optgroup{font-weight:bold;}table{border-collapse:collapse;border-spacing:0;}td,th{padding:0;}meta.foundation-version{font-family:"/5.2.3/";}meta.foundation-mq-small{font-family:"/only screen/";width:0em;}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.063em)/";width:40.063em;}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.063em)/";width:64.063em;}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.063em)/";width:90.063em;}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.063em)/";width:120.063em;}meta.foundation-data-attribute-namespace{font-family:false;}html,body{height:100%;}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html,body{font-size:100%;}body{background:#fff;color:#222;padding:0;margin:0;font-family:"Helvetica Neue","Helvetica",Helvetica,Arial,sans-serif;font-weight:normal;font-style:normal;line-height:1;position:relative;cursor:default;}a:hover{cursor:pointer;}img{max-width:100%;height:auto;}img{-ms-interpolation-mode:bicubic;}#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none !important;}.left{float:left !important;}.right{float:right !important;}.clearfix:before,.clearfix:after{content:" ";display:table;}.clearfix:after{clear:both;}.hide{display:none;}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}img{display:inline-block;vertical-align:middle;}textarea{height:auto;min-height:50px;}select{width:100%;}.row{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5rem;}.row:before,.row:after{content:" ";display:table;}.row:after{clear:both;}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0;}.row.collapse .row{margin-left:0;margin-right:0;}.row .row{width:auto;margin-left:-0.9375rem;margin-right:-0.9375rem;margin-top:0;margin-bottom:0;max-width:none;}.row .row:before,.row .row:after{content:" ";display:table;}.row .row:after{clear:both;}.row .row.collapse{width:auto;margin:0;max-width:none;}.row .row.collapse:before,.row .row.collapse:after{content:" ";display:table;}.row .row.collapse:after{clear:both;}.column,.columns{padding-left:0.9375rem;padding-right:0.9375rem;width:100%;float:left;}@media only screen{.small-push-0{position:relative;left:0%;right:auto;}.small-pull-0{position:relative;right:0%;left:auto;}.small-push-1{position:relative;left:8.33333%;right:auto;}.small-pull-1{position:relative;right:8.33333%;left:auto;}.small-push-2{position:relative;left:16.66667%;right:auto;}.small-pull-2{position:relative;right:16.66667%;left:auto;}.small-push-3{position:relative;left:25%;right:auto;}.small-pull-3{position:relative;right:25%;left:auto;}.small-push-4{position:relative;left:33.33333%;right:auto;}.small-pull-4{position:relative;right:33.33333%;left:auto;}.small-push-5{position:relative;left:41.66667%;right:auto;}.small-pull-5{position:relative;right:41.66667%;leLine truncated
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once("../../inside/functions.php");
|
|
||||||
|
|
||||||
/* Set HTTP response code */
|
/* Set HTTP response code */
|
||||||
function set_response_code($code) {
|
function set_response_code($code) {
|
||||||
@@ -153,4 +152,58 @@ function valid_phonenumber($phone) {
|
|||||||
function valid_email($email) {
|
function valid_email($email) {
|
||||||
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||||
}
|
}
|
||||||
|
/* Compare two hashes */
|
||||||
|
function hash_compare($a, $b) {
|
||||||
|
if (!is_string($a) || !is_string($b)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$len = strlen($a);
|
||||||
|
if ($len !== strlen($b)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = 0;
|
||||||
|
for ($i = 0; $i < $len; $i++) {
|
||||||
|
$status |= ord($a[$i]) ^ ord($b[$i]);
|
||||||
|
}
|
||||||
|
return $status === 0;
|
||||||
|
}
|
||||||
|
function create_token($user, $secret_key, $timestamp=NULL) {
|
||||||
|
// Based on this: https://github.com/django/django/blob/master/django/contrib/auth/tokens.py#L50
|
||||||
|
if($timestamp === NULL) {
|
||||||
|
$timestamp = date_format(date_create(), "Y-m-d");
|
||||||
|
}
|
||||||
|
$message = $user['memberid'].$user['registration_status'].$timestamp;
|
||||||
|
$user_hash = hash_hmac("sha256", $message, $secret_key);
|
||||||
|
|
||||||
|
return $timestamp. "," .$user_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_token($user, $token, $secret_key) {
|
||||||
|
/* Check that a password reset token is correct for a given user. */
|
||||||
|
|
||||||
|
// Parse the token
|
||||||
|
list($ts, $hash) = explode(",", $token);
|
||||||
|
|
||||||
|
// Check that the timestamp/uid has not been tampered with
|
||||||
|
if( !hash_compare(create_token($user, $secret_key, $ts), $token) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the timestamp is within limit
|
||||||
|
$n_days_ago = date_modify(date_create(), "-".REGISTRATION_URL_TIMEOUT_DAYS." days");
|
||||||
|
if( $n_days_ago > clean_date($ts) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function generate_registration_url($user, $secret_key) {
|
||||||
|
$token = create_token($user, $secret_key);
|
||||||
|
$server_name = isset($_SERVER['HTTP_X_FORWARDED_SERVER']) ? $_SERVER['HTTP_X_FORWARDED_SERVER'] : $_SERVER['SERVER_NAME'];
|
||||||
|
$url = $_SERVER["REQUEST_SCHEME"]."://".$server_name."/snapporder/activate.php?userid=".$user['memberid']."&token=$token";
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "inside-snapporder",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"node-sass": "latest",
|
||||||
|
"grunt": "latest",
|
||||||
|
"grunt-autoprefixer": "latest",
|
||||||
|
"grunt-contrib-watch": "latest",
|
||||||
|
"grunt-sass": "latest",
|
||||||
|
"matchdep": "latest"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// Comment out this import if you don't want to use normalize
|
||||||
|
@import './bower_components/foundation/scss/normalize';
|
||||||
|
|
||||||
|
// Or selectively include components
|
||||||
|
@import "foundation/components/grid";
|
||||||
|
|
||||||
|
@import "foundation/components/buttons";
|
||||||
|
@import "foundation/components/forms";
|
||||||
|
@import "foundation/components/block-grid";
|
||||||
|
@import "foundation/components/visibility";
|
||||||
|
|
||||||
|
body {
|
||||||
|
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
@include grid-row();
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
@include grid-column(12);
|
||||||
|
}
|
||||||
|
.about{
|
||||||
|
@include grid-column(12);
|
||||||
|
@media #{$medium-up} { @include grid-column(6); }
|
||||||
|
}
|
||||||
|
.activation {
|
||||||
|
@include grid-column(12);
|
||||||
|
@media #{$medium-up} { @include grid-column(6); }
|
||||||
|
.profile {
|
||||||
|
}
|
||||||
|
.activation-form {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.btn-submit {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
@media #{$medium-up} {
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in new issue
Block a user