From eb58554689c07cea153da84855a8811ad4c83d41 Mon Sep 17 00:00:00 2001 From: Enrico Fasoli Date: Sat, 4 Oct 2014 17:16:27 +0200 Subject: [PATCH] huge update with accounts and notifications, not yet finished --- .meteor/packages | 2 ++ .meteor/versions | 8 +++++++ client/client.coffee | 48 +++++++++++++++++++++++++++++++++++++++--- client/main.html | 3 +++ client/style.less | 19 +++++++++++++++++ client/templates.html | 45 ++++++++++++++++++++++++++++++++++++++- server/accounts.coffee | 27 ++++++++++++++++++++++++ server/server.coffee | 26 ++++++++++++++++++----- 8 files changed, 169 insertions(+), 9 deletions(-) create mode 100644 server/accounts.coffee diff --git a/.meteor/packages b/.meteor/packages index 3dadb4f..d0b0a93 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -10,5 +10,7 @@ coffeescript less perak:markdown natestrauser:font-awesome +accounts-password mrt:moment +reactive-var diff --git a/.meteor/versions b/.meteor/versions index 687ca0f..9187baf 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -1,3 +1,5 @@ +accounts-base@1.1.1 +accounts-password@1.0.2 application-configuration@1.0.2 autoupdate@1.1.1 base64@1.0.0 @@ -13,6 +15,7 @@ ctl@1.0.1 ddp@1.0.9 deps@1.0.4 ejson@1.0.3 +email@1.0.3 fastclick@1.0.0 follower-livedata@1.0.1 geojson-utils@1.0.0 @@ -28,6 +31,7 @@ jquery@1.0.0 json@1.0.0 less@1.0.9 livedata@1.0.10 +localstorage@1.0.0 logging@1.0.3 meteor-platform@1.1.1 meteor@1.1.1 @@ -38,6 +42,7 @@ mobile-status-bar@1.0.0 mongo@1.0.6 mrt:moment@2.8.1 natestrauser:font-awesome@4.2.0 +npm-bcrypt@0.7.7 observe-sequence@1.0.2 ordered-dict@1.0.0 perak:markdown@1.0.4 @@ -47,9 +52,12 @@ reactive-var@1.0.2 reload@1.1.0 retry@1.0.0 routepolicy@1.0.1 +service-configuration@1.0.1 session@1.0.2 +sha@1.0.0 spacebars-compiler@1.0.2 spacebars@1.0.2 +srp@1.0.0 templating@1.0.7 tracker@1.0.2 ui@1.0.3 diff --git a/client/client.coffee b/client/client.coffee index bcf227a..36d35a0 100644 --- a/client/client.coffee +++ b/client/client.coffee @@ -1,7 +1,10 @@ docs = new Meteor.Collection 'docs' +Meteor.subscribe 'user' +UI.registerHelper 'mail', -> Meteor.user().emails[0].address Router.configure layoutTemplate: 'layout' + loadingTemplate: 'loading' Router.map -> @route 'home', @@ -17,10 +20,30 @@ Router.map -> waitOn: -> @docHandle = Meteor.subscribe 'doc', @params._id data: -> docs.findOne @params._id action: -> - if @ready() - @render() + if @ready() then @render() else @render 'loading' + @route 'verify', + path: '/verify/:token' + template: 'loading' + onBeforeAction: -> + Accounts.verifyEmail @params.token, (err) -> + if err then errCallback err else Router.go 'home' @route 'new' + @route 'signup' + @route 'signin', path: 'login' + @route '404', path: '*' + +notification = new ReactiveVar() +share.notify = notify = (opt) -> + if !opt then notification.set undefined + else + opt.type ?= "danger" + notification.set opt +errCallback = (err) -> + if err.reason then notify msg: err.reason else notify msg: err +Template.notifications.notification = -> notification.get() +Template.notifications.events + 'click .close': -> notify() Template.layout.showSpinner = -> Meteor.status().connected is no or Router.current().ready() is no @@ -28,6 +51,25 @@ Template.home.ndocs = -> docs.find().count() Template.new.events 'click #new-btn': (e,t) -> id = docs.insert + title: t.find('#title').value text: t.find('#editor').value - if id? + dateCreated: moment().unix() + if id Router.go 'doc', _id: id + else notify msg: 'document creation failed' + +Template.signup.events + 'click #signup': (e,t) -> + if not t.find('#mail').value + return notify msg: 'please enter an email' + else if not t.find('#pw').value + return notify msg: "Please enter a password" + else if t.find('#pw').value isnt t.find('#rpw').value + return notify msg: "The passwords don't match" + else # Sending actual registration request + console.log t.find('#mail').value + Accounts.createUser { + email: t.find('#mail').value + password: t.find('#pw').value + }, (err) -> if err then errCallback err + else notify type: 'success', msg: 'check your email' diff --git a/client/main.html b/client/main.html index 8a3c31f..a2e7e5f 100644 --- a/client/main.html +++ b/client/main.html @@ -1,3 +1,6 @@ MarkCloud + + + diff --git a/client/style.less b/client/style.less index 16ef992..1d7ddab 100644 --- a/client/style.less +++ b/client/style.less @@ -1,7 +1,13 @@ +// Body .container { max-width: 40em; } +.close { + margin-top: -20px; +} + +// Loading and spinner #spinner { position: fixed; right: 1em; @@ -12,6 +18,19 @@ margin-top: 2em; } +// Editor #new-btn { margin-top: 1em; } + +// Sign up +#signup-container, #signin-container { + #mail { margin-top: 2em; } + #pw { + margin-top: 1em; + margin-bottom: 1em; + } + .btn { + margin-top: 1em; + } +} diff --git a/client/templates.html b/client/templates.html index bba3df0..cfde2b1 100644 --- a/client/templates.html +++ b/client/templates.html @@ -3,19 +3,25 @@

MarkCloud


+ {{> notifications}} {{> yield}}
+ + + + + + + + diff --git a/server/accounts.coffee b/server/accounts.coffee new file mode 100644 index 0000000..aaf54da --- /dev/null +++ b/server/accounts.coffee @@ -0,0 +1,27 @@ +# Homework - Server side accounts code + +# Regular Expression to see if an email can be valid +validateEmail = (email) -> + x = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/ + x.test email + +Accounts.config { + sendVerificationEmail: true + loginExpirationInDays: 5 +} + +# Code that checks if a new user request is valid +Accounts.validateNewUser (user) -> + user.dateCreated = moment().unix() + mail = user.emails[0].address + if Match.test(mail,String) is no or validateEmail(mail) is no + throw new Meteor.Error 403, "Invalid Email" + return yes + +# Email configuration code +Accounts.emailTemplates.siteName = "MarkCloud" +Accounts.emailTemplates.verifyEmail.text = (user,url) -> + urlist = url.split('/'); token = urlist[urlist.length-1] + url = Meteor.absoluteUrl 'verify/'+token + '''Welcome to MarkCloud! To activate your account, click on the \ + following link: '''+url diff --git a/server/server.coffee b/server/server.coffee index 6034203..b030d9b 100644 --- a/server/server.coffee +++ b/server/server.coffee @@ -1,9 +1,25 @@ docs = new Meteor.Collection 'docs' -Meteor.publish 'doc', (id) -> docs.find _id: id -Meteor.publish 'docs', -> docs.find() +validatedUser = (uid) -> + return no unless Meteor.users.findOne uid + u = Meteor.users.findOne uid + return yes for mail in u.emails when mail.verified is yes; no + +Meteor.publish 'doc', (id) -> docs.find {_id: id}, limit: 1 +Meteor.publish 'docs', -> docs.find {}, fields: text: 0 +Meteor.publish 'user', -> + if @userId + docs.find {_id:@userId}, fields: {dateCreated: 1} + else @ready() docs.allow - insert: -> yes - update: -> no - remove: -> no + insert: (uid,doc) -> + return no unless doc.text and doc.title + if uid then doc.owner = uid; return yes + else if doc.owner then return no + # Owners can update and remove their documents + update: (uid,doc) -> doc.owner is uid + remove: (uid,doc) -> doc.owner is uid + fetch: ['owner'] # Only fetch the owner field from the database documents + +# Save account creation date