From a8818652365b86a49b5c43df8725fd76565f55cd Mon Sep 17 00:00:00 2001 From: piatra Date: Thu, 8 Aug 2013 16:36:53 +0200 Subject: [PATCH] v0.3.0 --- app.js | 36 +++- lib/asset.js | 4 +- lib/keys.js | 1 - lib/payswarm.cfg | 6 +- lib/schemas.js | 9 +- lib/user.js | 13 ++ package.json | 11 +- public/images/bg-gradient-sand.png | Bin 0 -> 11398 bytes public/images/bg-sand.png | Bin 0 -> 2364 bytes public/images/payswarm.png | Bin 0 -> 453 bytes public/javascripts/event-handlers.js | 10 +- public/javascripts/upload.js | 72 +++++++ public/stylesheets/mixins.styl | 6 + public/stylesheets/style.css | 89 +++++++-- public/stylesheets/style.styl | 106 ++++++++-- public/stylesheets/topcoat-mobile-light.css | 42 ++-- routes/assets.js | 211 +++++++++++++++----- routes/assets/140110e6550 | 114 +++++++++++ routes/assets/14011124869 | 114 +++++++++++ routes/auth.js | 2 + routes/index.js | 47 ++--- test.js | 33 --- views/asset-purchase.jade | 20 ++ views/index.jade | 25 ++- views/layout.jade | 12 +- views/login.jade | 11 + views/newasset.jade | 18 +- views/preview-selection.jade | 16 ++ views/test.jade | 6 + 29 files changed, 831 insertions(+), 203 deletions(-) create mode 100644 public/images/bg-gradient-sand.png create mode 100644 public/images/bg-sand.png create mode 100644 public/images/payswarm.png create mode 100644 public/javascripts/upload.js create mode 100644 public/stylesheets/mixins.styl create mode 100644 routes/assets/140110e6550 create mode 100644 routes/assets/14011124869 delete mode 100644 test.js create mode 100644 views/asset-purchase.jade create mode 100644 views/login.jade create mode 100644 views/preview-selection.jade create mode 100644 views/test.jade diff --git a/app.js b/app.js index fd16b1d..dd635aa 100644 --- a/app.js +++ b/app.js @@ -33,8 +33,19 @@ app.configure('development', function(){ app.use(express.errorHandler()); }); +function requireLogin(req, res, next) { + if (req.session.email) { + next(); // allow the next route to run + } else { + // require the user to log in + res.redirect("/login"); // or render a form, etc. + } +} + app.get('/', routes.index); +app.get('/login', routes.login); + app.post('/user/set/username', user.setUsername); app.post('/auth/verify', auth.verify); @@ -44,7 +55,11 @@ app.get('/auth/createKeyPair', auth.createKeyPair); app.post('/payswarm/register', auth.registerKey); app.post('/payswarm/complete', auth.complatePayswarmRegistration); -app.get('/newasset', routes.newasset); + +/* + New asset +*/ +app.get('/newasset', requireLogin, routes.newasset); app.post('/newasset/process/', assets.createAssetAndListing); app.post('/newasset/save', assets.saveAsset); @@ -54,16 +69,29 @@ app.get('/assets/:count', assets.getLatestAssets); app.get('/resign/listing/:id', assets.resignListing); app.get('/assets/asset/:id', assets.getAsset); + +app.get('/assets/asset/:id/purchase', assets.purchase); +app.post('/assets/asset/:id/purchased', assets.purchased); +app.post('/assets/asset/:id/preview', assets.preview); +app.get('/assets/asset/:id/preview', assets.preview); + app.get('/listings/listing/:id', assets.getListing); -app.get('/asset/content/:id', function (req, res){ +app.get('/assets/asset/:id/content', function (req, res){ res.end('The content!'); }); -app.get('/assets/:id/purchase', assets.purchase); - app.get('/decrypt/:type/:id', assets.decrypt); +app.get('/test', function (req, res){ + res.render('test'); +}); + +app.post('/upload', function (req, res) { + console.log(req.files); + res.json(req.files); +}); + http.createServer(app).listen(app.get('port'), function(){ console.log("Express server listening on port " + app.get('port')); }); diff --git a/lib/asset.js b/lib/asset.js index f4636f9..266a60f 100644 --- a/lib/asset.js +++ b/lib/asset.js @@ -150,9 +150,9 @@ module.exports = function (options) { db.get.asset(query, function (err, doc) { if (err) { console.log('Error getting one asset' + err); - cb({}); + cb(err, {}); } else { - cb(doc); + cb(null, doc); } }); } diff --git a/lib/keys.js b/lib/keys.js index 6fea608..7945e75 100644 --- a/lib/keys.js +++ b/lib/keys.js @@ -17,7 +17,6 @@ module.exports = function(opts) { console.log('Error reading keys: ', err); } else { keyPair = JSON.parse(data); - console.log('PRIVATE KEY PEM', keyPair); payswarm.decrypt(encryptedMessage, {privateKey: keyPair.publicKey.privateKeyPem}, cb); } }); diff --git a/lib/payswarm.cfg b/lib/payswarm.cfg index 2ea72cf..7e51264 100644 --- a/lib/payswarm.cfg +++ b/lib/payswarm.cfg @@ -3,8 +3,8 @@ "publicKey": { "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApJTzBuohTPiqliU5Vu8o\nfVZcRIAR16BCVd1CdY65SGOfQuiN3xsK5T4ZGQQiyAogdpYhiGEqB/wgqNr3Wzjv\nC2jxBHLHsiNRGvWkRFqFA8axlqyTkXlSV9fXKbFX0hwrqSByy4JzaNxGA74wYBtH\n2b1nLEIGPE8biB+hywWADPNWSUO/QYm9LRGYuFbl/ieDB9kF8w+JMyzX3yYI45KS\nd979n2ucMgXZ7zMoY9cQKdnaqYINjtMhSW1oTJ03CY5N1v6y5Fx1G2m8fh+X1Qpl\n23LauzIa4T+wWCv7d34kE1DmQEOShtVc8rvpjp6Qz41HOz/bJSa8DAr3xUxPco9G\nGQIDAQAB\n-----END PUBLIC KEY-----\n", "privateKeyPem": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEApJTzBuohTPiqliU5Vu8ofVZcRIAR16BCVd1CdY65SGOfQuiN\n3xsK5T4ZGQQiyAogdpYhiGEqB/wgqNr3WzjvC2jxBHLHsiNRGvWkRFqFA8axlqyT\nkXlSV9fXKbFX0hwrqSByy4JzaNxGA74wYBtH2b1nLEIGPE8biB+hywWADPNWSUO/\nQYm9LRGYuFbl/ieDB9kF8w+JMyzX3yYI45KSd979n2ucMgXZ7zMoY9cQKdnaqYIN\njtMhSW1oTJ03CY5N1v6y5Fx1G2m8fh+X1Qpl23LauzIa4T+wWCv7d34kE1DmQEOS\nhtVc8rvpjp6Qz41HOz/bJSa8DAr3xUxPco9GGQIDAQABAoIBAHjDMm/oa/bmn4T8\nW06Gvdb5/0nkDzOAzCvk5lcMGrgbIUkfCrqiRSRgpFnOxxaxF5DsKD7BzO1++xfr\nU4UECaL9pZv1/MGhWGnHxHjDUsaqjLRafQ1JUDpUjfRxxFbPhNncjV72oWhX+KfW\nbfiXC+mhKIs5BwpJoZIIY9dsecEFvxZGl7P5OdWYc7+6/ap/CS6r6H9b1a2Z9XZq\nGmHldvQa6mXJn8G/HT2QOKSThRbhQjgNVxhofjUYcSqgBdQFT7rd1BEEK0cDw1eR\nfcie812QefSjRWog1uJjXFuS81zfxTWrepRZuKgscKSwykyhr3AUh59tR25HHJZr\n76kyxAECgYEAzo0959lGa8Zqw3MyjYeaMMBW+Pd27FaoHOsVEGLtPohug4q0o/AO\n8pusO1JBSmpb4/LSgYo46/Gp6iIg5d6t4Ttnwx8n/qPH3t+ezTgsrh9CPf2glSEe\nGvdT3tr1WCFjVV3HiJaXFxUjrkPmEcG/L/QtV4TV+aCMOx5GyckAEikCgYEAy/uI\n5bQQ0c/VVSmi7sWHYcs1GPmy/ahZcagMSB80NUNfG9QhB0YEMler8fDa159YsV9W\nwRhog83Ip8I48IMwTOvBGuBKPsl+Hw9hNG8ksRE4BnXy/y82Jf3xCGM2u+7Cf2/f\n/i9WLli71NFV6LrdJUelvpciANX5a10rkF4JcnECgYBcTnKj8k2uTHXZ8tlctoUJ\n1GsJyE21QOTQR56aPBuaHo6E6q/fs6B6e2d0+0WCZBW8wP+iNItLpiwxHh9lmyZJ\nyaqNYJcXDUp9J6JoQ/pztjR8T6Q8ARjbJDyvE1shj4o81DQfrmzHPAM+FcnzlYpD\ne/PncM3PSRhiMx2ff9wwQQKBgBWrSOWt9UN0oqMDY02eKj2XSrK2g+8yXR4XzgYz\nWmZ2G7pnFIMjSvrWGWwAPB8/zDo7eInWv/OQfspjdY0HQrBJMyBZx0lYOk+uYJMj\nY3Bz9dGp4gB90XDDw0Ey2POp73t+NPtZp/wQbRO0kT3B7BAzxkWy5GfWU0K2iRQz\nCSnhAoGBAMnJ5266sq9ETo0taO15B7pkBLE48+jmLkYMRmu4iHnGYlqJcQxh/evv\nDZ8XbysUGgmT3TcEXqg/lwL8WxXtvqDCOlA7SIncf4tRW1RjcntWfCduWOP8SAe1\n+yXmQQnoqiBCSGswXLFtv3udWCbSJ5rl8e/dKFSMDuDUUXhKLaKK\n-----END RSA PRIVATE KEY-----\n", - "id": "https://dev.payswarm.com/i/webpayments/keys/3" + "id": "https://dev.payswarm.com/i/webpay/keys/1" }, - "owner": "https://dev.payswarm.com/i/webpayments", - "source": "https://dev.payswarm.com/i/webpayments/accounts/primary" + "owner": "https://dev.payswarm.com/i/webpay", + "source": "https://dev.payswarm.com/i/webpay/accounts/primary" } \ No newline at end of file diff --git a/lib/schemas.js b/lib/schemas.js index 579759d..1f19c8e 100644 --- a/lib/schemas.js +++ b/lib/schemas.js @@ -10,7 +10,11 @@ var UserSchema = new Schema({ publicKeyUrl : String, owner : String, destination : String, - username: String + username: String, + preferences: { + hasBudget: Boolean + }, + purchases: [String] }); var PayeeSchema = { @@ -38,6 +42,8 @@ var AssetSchema = { }, title: String, assetContent: String, + assetFiles: [String], + assetPreview: [String], assetProvider: String, signature : Object, assetDescription: String, @@ -61,6 +67,7 @@ var ListingSchema = { payeeRule: Array, asset: String, assetHash: String, + _listingHash: String, license: String, licenseHash: String, validFrom: String, diff --git a/lib/user.js b/lib/user.js index 490e3e6..045f7a8 100644 --- a/lib/user.js +++ b/lib/user.js @@ -16,9 +16,22 @@ module.exports = function (opts) { db.get.user(fields, user, cb); } + function addPurchase (assetId, user, cb) { + get({purchases:1}, user, function (err, user) { + if (err) { + console.log('error retrieving user'); + cb(err); + } else { + user.purchases.push(assetId); + user.save(cb); + } + }); + } + userUtils.checkUser = checkUser; userUtils.updateFields = updateFields; userUtils.get = get; + userUtils.addPurchase = addPurchase; return userUtils; }; \ No newline at end of file diff --git a/package.json b/package.json index c8770f7..1c85aa4 100644 --- a/package.json +++ b/package.json @@ -21,17 +21,18 @@ "mongoose": "~3.6.11", "q": "~0.9.6", "underscore": "~1.4.4", - "highlight.js": "~7.3.0" + "highlight.js": "~7.3.0", + "formidable": "~1.0.14" }, "subdomain": "webpayments", "engines": { "node": "0.8.x" }, - "repository" : { - "type" : "git", - "url" : "https://github.com/piatra/webpayments-marketplace" + "repository": { + "type": "git", + "url": "https://github.com/piatra/webpayments-marketplace" }, "devDependencies": { "requirejs": "~2.1.6" } -} \ No newline at end of file +} diff --git a/public/images/bg-gradient-sand.png b/public/images/bg-gradient-sand.png new file mode 100644 index 0000000000000000000000000000000000000000..ae82378ae8823fe984af7a4c2e1b17b19be5e1f3 GIT binary patch literal 11398 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 U+om`ox&QzG07*qoM6N<$f*5e+Bme*a literal 0 HcmV?d00001 diff --git a/public/images/bg-sand.png b/public/images/bg-sand.png new file mode 100644 index 0000000000000000000000000000000000000000..6b2d79d9ce1e2fd1980dbb0b18c7ac80d833ee47 GIT binary patch literal 2364 zcmV-C3B&e@P)*Va}8Zy-Prbh9Wef`vpTQ0E9+QEU8Tr7uAT7a zLRabAoyr4=A&xmmGl3SUH^z90;v6=?sA{rOGZjSUB2T(#xb$`VeYlOYhs3pWs|rH! z4zl!O;b7%`j^bozYAdZQ-H+d13Vcs>U!80|mMT(;t=Vyyn%p+_itBm^i&W(vj1TwX zZerx}2FcM$z#h+@m};Qwpe1z3=lTlBZ`bjGB?^9$`np+zoSHMb`5&D_U#TZIyj@1d#Q@EWwsOFy-l+nr_QY?5RXov7DWg}u>s zlqq^vW3tGX>7m{!4%dyLys9NlqT)!Gm$Ip$zBNWfnewf7vJ0DTRC2_Ig`vjQR1DmE z-RsMDzLy!N`0UbX(*@IAFc3|J?9)tRk`YIozXLvecW zzf}mCoyywx_)9hbGwKnWl`j_htF)~DO=(d@VcsRpjc&2cJ8WOwOR!T`U(tyjc@)PEVX!O>c)-Yiq>BT(Sv!YX#4aHR@`tXnJJy zJtNYH;jB;gXy&l9&t8^F*B#&{ZihvnwXUOxB;KfQIkiy|jXbtTMEI3COOu|pal8@q zBCm_5JLK8m?ns*`Ho10UA029Ix45k&^F}Hir*fk8rb$md!DQn)cN?bH(4d4=HD z`5wBCiJ|%?5pAR6Gl99PSt)G}fmgDpbB~egyr@H$>{L*um{)srI&AX_rgB{<{(_~r3V6}IGGdAeWm?&qkMp>0jY_8^%jC|*vtC-}xZMVs5JV#GZ+?P&`t~`uu*@@T3O)?7n z!E`IRlD$V`1I^>2gD>l zui`1$K9f=3m@@F8230g>)(;;dLT__X-g1tE+HEeOa$dU3^HM-upL6T%%cX0>#8}wQ zd>llSP$haU;7?X2`Y?Aa{zqif^VI$(Uip1R7k&7w@jEfY$USJ@XWu(NaAIGweDd4J z!S>1D`&U;^2~6$%h!@;fV;R-fWxYLSe1yb|=;#&nd>Mgqa@`FnGf|#~4~{3@-Uhes zhkW(?qdkAB!Ek_c&p215H1%LBhbl3!EdD95(Q`99EI!uo@|mi0n#E>J9Tj0sz;-%g z>{Z@Cw#xj-LF*~YCvk%JBQH50$`e2B#jp5DJ?~QHIu!izUuqlIahwlt>wG&7X1nIlkz_R`ei42#xef|1U+?d#XIA1 zw(%?5k#;2KyviUZlQ?N~(h9FKc`e29apvspJ065oBM3v>;G{xKHulN#ZrW`+{GA=t zv%~(Px&5yuLw{;MjQ_1n{A|#sUfEXc?C;6o-(>i z_*)VW?S%N7jB@nM2fm6_bYj#d-k+0F zX~iyyb@>FbT$hi2(HyUPD4l2F$g1?1Pa z{gi%vG)tH`zZFmFaaZ|$ApNn_={dUj&9MA$t)HG_mwyrX{8FFSa{%y5_PXK(u*N*|q;hGW6uJ2H6eT=lD^Ixx>eP zb)*jRHXdxAI8w9O!>#;51FphP^`1u>32%`_mcd8NhylJ^W$MliU&M2T1(du+mP`fXDN$+-EDa^rVBYN9{l3 zX*-tFgg!1AfGzwn8LPl>Lc(dYjn`%@A;hbJLi{EJAf9@MfP{voMs_L!g=5h7z37pa!Tqik#GPQ1g?QC-~^Zj zt`daRsJ_at8d~b6T2!ahGxaUzU(Bh5gr$V&&%h0E8>XKJc2EPgq^_!uDX)324y&Nf zg@*@fpSqC{psMzVrGdH~bJo-aHLs4SE9#zluJ-uTb5M8xh~5kZiKG~DKUUj%8Y!|oa0rZsjlE1I#fYd! v>Z{tBl^AUbw&$~uRT%w_22cWevu64Y-be&jz2JyZ00000NkvXXu0mjff?dEK literal 0 HcmV?d00001 diff --git a/public/javascripts/event-handlers.js b/public/javascripts/event-handlers.js index ff1394b..a92ba5d 100644 --- a/public/javascripts/event-handlers.js +++ b/public/javascripts/event-handlers.js @@ -1,8 +1,10 @@ define([ 'message', 'event-login', - 'event-assets' - ], function (message, loginEv, assetsEv) { + 'event-assets', + 'modal', + 'upload' + ], function (message, loginEv, assetsEv, modal, upload) { var verify = { assertion : function (assertion) { @@ -40,7 +42,7 @@ define([ navigator.id.request(); }); - $('.js-handler--create-asset').on('submit', assetsEv.create(assetsEv.assetCreated)); + // $('.js-handler--create-asset').on('submit', assetsEv.create(assetsEv.assetCreated)); $('.js-handler--change-username').on('submit', assetsEv.create(assetsEv.usernameChanged)); @@ -51,6 +53,8 @@ define([ }).success(loginEv.displayPayswarmMsg); } + //$('input[type=file]').on('change', upload.sendFile); + assetsEv.loadLatest($('.container--newest')); } diff --git a/public/javascripts/upload.js b/public/javascripts/upload.js new file mode 100644 index 0000000..a6836ed --- /dev/null +++ b/public/javascripts/upload.js @@ -0,0 +1,72 @@ +define([], function () { + + function readFile (file) { + var reader = new FileReader(); + // Closure to capture the file information. + reader.onload = (function(theFile) { + return function(e) { + // FIXME (emit events?) + // Render thumbnail. + var span = document.createElement('span'); + span.innerHTML = ['

', + 'Is this a preview ?

'].join(''); + $('#preview').html(span); + }; + })(file); + + // Read in the image file as a data URL. + reader.readAsDataURL(file); + } + + function sendFile () { + var formData = new FormData(); + var file = this.files[0]; + var progress = document.createElement('progress'); + progress.value = 0; + progress.max = 100; + progress.innerHTML = '0%' + $(this).replaceWith(progress); + + if (file.type.match('image.*')) { + $('button[type=submit]').attr('disabled', true); + readFile(file); + } + + var attached = $('.js-handler--filesAttached')[0].innerHTML.split(', '); + attached.push(escape(file.name)); + $('.js-handler--filesAttached')[0].innerHTML = attached.join(', '); + + formData.append('myFile', file); + + var xhr = new XMLHttpRequest(); + + xhr.open('post', '/upload', true); + + xhr.upload.onprogress = function(e) { + if (e.lengthComputable) { + var percentage = (e.loaded / e.total) * 100; + $('progress').attr('value', percentage).text(percentage + '%'); + } + }; + + xhr.onerror = function(e) { + console.log('An error occurred while submitting the form. Maybe your file is too big'); + }; + + xhr.onload = function() { + if (this.status == 200) { + var $fileInput = $(''); + $('progress').replaceWith($fileInput); + $fileInput.on('change', sendFile); + $('button[type=submit]').attr('disabled', false); + } + }; + + xhr.send(formData); + } + + return { + sendFile: sendFile + } +}) \ No newline at end of file diff --git a/public/stylesheets/mixins.styl b/public/stylesheets/mixins.styl new file mode 100644 index 0000000..3246a31 --- /dev/null +++ b/public/stylesheets/mixins.styl @@ -0,0 +1,6 @@ +metrics-reset() + margin 0 + padding 0 + +warningBg = #FFFFBF +var-item__title-color = #0096dd \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 5bd633e..d5dc70d 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -11,6 +11,7 @@ body { -webkit-justify-content: center; justify-content: center; color: #333; + background: url("../images/bg-gradient-sand.png") repeat-x 0 0, url("../images/bg-sand.png") repeat 0 0, #f5f1e8; } a { color: #00b7ff; @@ -31,25 +32,30 @@ a { padding: 0; } .item-container li { - background: #fff; - margin: 0 1rem 0 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 3rem 0; padding: 1rem; height: 150px; - max-width: 20%; + width: 25%; list-style: none; - -webkit-flex: auto; - flex: 1 1 auto; - -webkit-transition-duration: 0.3s; - border-bottom: 2px solid rgba(0,0,0,0.2); + display: inline-block; + border-right: 1px dotted rgba(0,0,0,0.4); } -.item-container li .topcoat-button--cta { - display: none; +.item-container li img { + max-width: 50px; + border: 2px solid #fff; + box-shadow: 0 0 3px rgba(0,0,0,0.2); + margin: 0 0.2rem; } -.item-container li:hover .topcoat-button--cta { - display: block; +.item-container li h4 { + font-size: 1.5rem; + margin-bottom: 0; + color: #0096dd; + text-shadow: 0 1px 0 rgba(255,255,255,0.75); } .category__title { - background: #fff; padding: 1rem; margin: 0; } @@ -122,6 +128,16 @@ a { .pull-left { float: left; } +.padding5 { + padding: 0.5rem; + box-sizing: border-box; +} +.buy--cta { + background: #288edf url("../images/payswarm.png") no-repeat; + background-position: 80% center; + width: 50%; + cursor: pointer; +} .small { height: auto; line-height: 0.6rem; @@ -161,7 +177,9 @@ table td { text-align: left; } .table-form tr:nth-child(even) { - background: #ddd; + background: rgba(0,0,0,0.02); + border-top: 1px solid rgba(0,0,0,0.04); + border-bottom: 1px solid rgba(0,0,0,0.04); } .see-more { opacity: 0.5; @@ -176,6 +194,12 @@ table td { .inline { display: inline-block; } +.well { + background: rgba(0,0,0,0.02); + box-shadow: inset 0 0 5px rgba(0,0,0,0.2); + border-bottom: 1px solid rgba(255,255,255,0.7); + border-radius: 3px; +} .margin-top { margin-top: 1rem; } @@ -236,3 +260,42 @@ table td { max-height: 200px; overflow: scroll; } +.tab-bar { + margin: 0; + padding: 0; + display: inline-block; +} +.max-width--200 { + max-width: 200px; +} +.inline-block { + display: inline-block; + width: 30%; +} +hr { + margin: 2rem 0; + background: none; + border: none; + border-top: 1px solid rgba(0,0,0,0.1); + border-bottom: 1px solid rgba(255,255,255,0.3); +} +.bubble:before, +.bubble--info:before { + content: ''; + display: inline-block; + min-width: 1rem; + min-height: 1rem; + border-radius: 50%; + text-align: center; + font-weight: 200; + line-height: 1rem; + color: #fff; + margin: 0 0.1rem; +} +.bubble--info:before { + content: '!'; + background: #2b9ed0; +} +.tab-bar li { + display: inline-block; +} diff --git a/public/stylesheets/style.styl b/public/stylesheets/style.styl index 469cfd7..13027ce 100644 --- a/public/stylesheets/style.styl +++ b/public/stylesheets/style.styl @@ -1,4 +1,4 @@ -warningBg = #FFFFBF +@import mixins body font: 14px "Lucida Grande", Helvetica, Arial, sans-serif @@ -13,6 +13,7 @@ body -webkit-justify-content center justify-content center color #333 + background url(../images/bg-gradient-sand.png) repeat-x 0 0,url(../images/bg-sand.png) repeat 0 0,#f5f1e8 a color #00B7FF @@ -30,30 +31,39 @@ a -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; - padding 0 + padding 0; li - background #fff - margin 0 1rem 0 0 + -webkit-box-sizing border-box + -moz-box-sizing border-box + box-sizing border-box + margin 3rem 0 padding 1rem height 150px - max-width 20% + width 25% list-style none - -webkit-flex: auto - flex: 1 1 auto; - -webkit-transition-duration .3s - border-bottom 2px solid rgba(0,0,0,.2) - -.item-container - li - .topcoat-button--cta - display none - li:hover - .topcoat-button--cta - display block + display inline-block + border-right 1px dotted rgba(0,0,0,.4); + img + max-width 50px + border 2px solid #fff + box-shadow 0 0 3px rgba(0,0,0,.2) + margin 0 .2rem + h4 + font-size 1.5rem + margin-bottom 0 + color var-item__title-color + text-shadow 0 1px 0 rgba(255,255,255,0.75) + +// .item-container +// li +// .topcoat-button--cta +// display none +// li:hover +// .topcoat-button--cta +// display block .category__title - background #fff padding 1rem margin 0 @@ -125,6 +135,16 @@ a .pull-left float left +.padding5 + padding .5rem + box-sizing border-box + +.buy--cta + background #288edf url(../images/payswarm.png) no-repeat + background-position 80% center + width 50% + cursor pointer + .small height auto line-height .6rem @@ -160,7 +180,9 @@ table th, table td td:nth-child(2) text-align left tr:nth-child(even) - background #ddd + background rgba(0,0,0,.02) + border-top 1px solid rgba(0,0,0,.04) + border-bottom 1px solid rgba(0,0,0,.04) .see-more opacity .5 @@ -175,6 +197,12 @@ table th, table td .inline display inline-block +.well + background rgba(0,0,0,.02) + box-shadow inset 0 0 5px rgba(0,0,0,.2) + border-bottom 1px solid rgba(255,255,255,.7) + border-radius 3px + .margin-top margin-top 1rem @@ -234,4 +262,42 @@ table th, table td .list--medium max-height 200px - overflow scroll \ No newline at end of file + overflow scroll + +.tab-bar + metrics-reset() + display inline-block + +.max-width--200 + max-width 200px + +.inline-block + display inline-block + width 30% + +hr + margin 2rem 0 + background none + border none + border-top 1px solid rgba(0,0,0,.1) + border-bottom 1px solid rgba(255,255,255,.3) + +.bubble:before + content '' + display inline-block + min-width 1rem + min-height 1rem + border-radius 50% + text-align center + font-weight 200 + line-height 1rem + color white + margin 0 .1rem + +.bubble--info:before + @extends .bubble:before; + content '!'; + background #2B9ED0; + +.tab-bar li + display inline-block \ No newline at end of file diff --git a/public/stylesheets/topcoat-mobile-light.css b/public/stylesheets/topcoat-mobile-light.css index 5c3fdd8..b4762f7 100644 --- a/public/stylesheets/topcoat-mobile-light.css +++ b/public/stylesheets/topcoat-mobile-light.css @@ -690,7 +690,6 @@ Navigation Bar height: 5rem; padding-left: 1rem; padding-right: 1rem; - background: #e5e9e8; color: #000; -webkit-box-shadow: inset 0 -1 #b9bcbc, 0 1px rgba(0,0,0,0.95); box-shadow: inset 0 -1 #b9bcbc, 0 1px rgba(0,0,0,0.95); @@ -826,33 +825,18 @@ limitations under the License. */ .topcoat-search-input, .topcoat-search-input--large { - vertical-align: top; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 0 1.25rem; - -webkit-border-radius: 6px; + padding: 0 1.8rem; border-radius: 6px; - margin: 5px; - height: 3rem; - font: inherit; font-weight: 200; outline: none; border: 1px solid #a5a8a8; background-color: #e5e9e8; - -webkit-box-shadow: inset 0 1px rgba(0,0,0,0.12); box-shadow: inset 0 1px rgba(0,0,0,0.12); color: #454545; - -webkit-appearance: none; - padding: 0 0 0 2.7em; - -webkit-border-radius: 15px; + font-size: 1rem; border-radius: 15px; - background-image: url("../img/search.svg"); - background-position: 1em center; - background-repeat: no-repeat; - -webkit-background-size: 12px; - -moz-background-size: 12px; - background-size: 12px; + margin-top: 1.5rem; + height: 2rem; } .topcoat-search-input:focus, .topcoat-search-input--large:focus { @@ -1046,4 +1030,22 @@ Topcoat Large Textarea font-size: 1.3rem; font-weight: 200; line-height: 2.6rem; +} + +progress { + margin: 14px 5px; + width: 99%; +} + +.thumb { + max-width: 200px; + border:3px solid #fff; + box-shadow: 0 0 3px rgba(0,0,0,.1); +} + +.preview-check { + width:200px; + height:200; + overflow:hidden; + position:relative; } \ No newline at end of file diff --git a/routes/assets.js b/routes/assets.js index 3789f2a..7ae746b 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -1,9 +1,11 @@ var asset = require('../lib/asset')(); var keys = require('../lib/keys')(); var payswarm = require('payswarm'); +var request = require('request'); var fs = require('fs'); var async = require('async'); var _ = require('underscore'); +var user = require('../lib/user')(); var HOST = 'https://webpayments.fwd.wf'; var assets = { @@ -12,6 +14,29 @@ var assets = { var assetId = new Date().getTime().toString(16); var k; async.waterfall([ + function (callback) { + console.log('getting & writing files'); + var l = req.files.files.length; + if (!_.isArray(req.files.files)) { + req.files.files = [req.files.files]; + l = 1; + } + req.files.files.forEach(function (file) { + fs.readFile(file.path, function (err, data) { + var newPath = __dirname + "/../public/uploads/" + assetId + '_' + file.name; + fs.writeFile(newPath, data, function (err) { + console.log('done writing', err); + if (err) { + console.log('an error occured'); + callback(err); + } else { + if (--l == 0) + callback(null); + } + }); + }); + }); + }, function(callback) { // read the config file from disk keys.getKeyPair(function(err, keysPair) { @@ -37,8 +62,9 @@ var assets = { userId: req.body.userId }, title: req.body.title, - assetContent: assetUrl, - assetProvider: req.body.owner, + assetContent: assetUrl + '/content', + assetFiles: req.files.files.map(function (f) { return f.name }), + assetProvider: 'https://dev.payswarm.com/i/webpay', listingRestrictions: { validFrom: payswarm.w3cDate(new Date(req.body.validFrom)), validUntil: payswarm.w3cDate(new Date(req.body.validUntil)), @@ -48,7 +74,7 @@ var assets = { destination: req.body.source, currency: 'USD', payeeGroup: ['assetProvider'], - destination: 'https://dev.payswarm.com/i/webpayments/accounts/incoming-payments', + destination: 'https://dev.payswarm.com/i/webpay/accounts/primary', payeeRate: '80', payeeRateType: 'Percentage', payeeApplyType: 'ApplyInclusively', @@ -92,17 +118,17 @@ var assets = { id: listingUrl, assetId: assetId, type: ['Listing', 'gr:Offering'], - vendor: req.body.owner, + vendor: 'https://dev.payswarm.com/i/webpay', payee: [{ id: listingUrl + '/payee', type: 'Payee', - destination: 'https://dev.payswarm.com/i/webpayments/accounts/incoming-payments', + destination: 'https://dev.payswarm.com/i/webpay/accounts/primary', currency: 'USD', payeeGroup: ['vendor'], payeeRate: req.body.price, payeeRateType: 'FlatAmount', payeeApplyType: 'ApplyExclusively', - comment: req.body.comment + ' [' + assetId + '].' + comment: req.body.comment }], payeeRule : [{ type: 'PayeeRule', @@ -138,15 +164,9 @@ var assets = { console.log(JSON.stringify(assetAndListing, null, 2)); - fs.writeFile(__dirname + '/assets/' + assetId, JSON.stringify(assetAndListing, null, 2), function (err) { - if (err) { - console.log(err); - } else { - asset.save(assetAndListing, function(err, result) { - callback(err, assetAndListing); - }); - } - }) + asset.save(assetAndListing, function(err, result) { + callback(err, assetAndListing); + }); }, function(assetAndListing, callback) { // display registration details @@ -168,9 +188,10 @@ var assets = { console.log('Failed to register signed asset and listing:', err.toString()); } else { - res.json({ - 'error' : null, - 'message': 'Asset and listing created successfully' + res.render('preview-selection.jade', { + 'title': 'WebPayments Marketplace', + 'files': req.files.files, + 'id': assetId }); } }); @@ -217,40 +238,69 @@ var assets = { purchase: function (req, res) { // this is a big FIXME - if (!req.session.identity) res.end('not logged in '); - else { - keys.getKeyPair(function(err, k) { - k = JSON.parse(k); - fs.readFile(__dirname + '/assets/' + req.params.id, function (err, data) { - json = JSON.parse(data); - payswarm.purchase(json['@graph'][1], { - transactionService: 'https://dev.payswarm.com/transactions', - customer: req.session.identity, - source: req.session.identity, - privateKeyPem: k.publicKey.privateKeyPem, - publicKey: 'https://dev.payswarm.com/i/webpayments/keys/3', - verbose: true - }, function(err, receipt) { - if (err) { - console.log(JSON.stringify(err, null,2)); - } else { - console.log('Receipt:', receipt); - console.log('Transaction ID:', receipt.contract.id); - } - }); + var id = req.params.id; + var authority = 'https://dev.payswarm.com/'; + // if user purchased asset + user.get({purchases:1,preferences:1}, {owner:req.session.identity || 'https://dev.payswarm.com/i/piatra'}, function (err, docs) { + console.log(docs, 'for', {owner:req.session.identity}); + if (err) { + console.log(err); + res.end('Error!'); + } else { + // show the asset page + if (~docs.purchases.indexOf(id)) { + res.render('asset-purchase', { + message: 'You have purchased this asset before' + }) + // else redirect + } else { + if (docs.preferences.hasBudget) { + // get the money from the budget he has set up + request.get({url : HOST + '/listings/listing/' + id, json: true}, function (err, resp, listing) { + keys.getKeyPair(function (err, data) { + if (err) { + cb(err); + } else { + data = JSON.parse(data); + payswarm.purchase(listing, { + transactionService: authority + 'transactions', + customer: req.session.identity, + publicKey: data.publicKey.id, + privateKeyPem: data.publicKey.privateKeyPem, + verbose: true + }, function (err, receipt){ + console.log(err, receipt); + }); + } + }); + }) + } else { + // take him to the payswarm website + assets._purchaseRedirect (req, function (url) { + res.redirect(url); + }); + } + } + } + }) + }, - }) + _purchaseRedirect: function (req, cb) { + var id = req.params.id; + var href = (process.env.NODE_ENV) ? 'http://webpayments.jit.su' : 'https://webpayments.fwd.wf'; + request.get({url: href+'/listings/listing/' + id, json: true}, function (err, response, body){ + payswarm.hash(body, function (err, hash) { + var url = 'https://dev.payswarm.com/profile/login?ref=/transactions?form=pay'; + url += encodeURIComponent('&listing=' + href + '/listings/listing/' + id); + url += encodeURIComponent('&listing-hash=' + hash); + url += encodeURIComponent('&callback=' + href + '/assets/asset/' + id + '/purchased?id=' + req.session.id); + url += encodeURIComponent('&response-nonce=12345678'); + cb(url); }) - - } - + }); }, getListing: function (req, res) { - // fs.readFile(__dirname + '/assets/' + req.params.id, function (err, data) { - // data = JSON.parse(data); - // res.json(data['@graph'][1]); - // }); var query = {'assetId': req.params.id}; asset.getListing(query, function (doc) { res.json(doc); @@ -258,10 +308,6 @@ var assets = { }, getAsset: function (req, res) { - // fs.readFile(__dirname + '/assets/' + req.params.id, function (err, data) { - // data = JSON.parse(data); - // res.json(data['@graph'][0]); - // }); var query = {'listingId': req.params.id}; asset.getAsset(query, function (doc) { res.json(doc); @@ -331,6 +377,52 @@ var assets = { }); }, + purchased: function (req, res) { + req.body = JSON.stringify(req.body, null, 2); + body = JSON.parse(req.body); + body = JSON.parse(body['encrypted-message']); + var url_parts = url.parse(req.url, true); + var query = url_parts.query; + + keys.decode(body, function (err, resp){ + if (err) { + console.log(err); + res.end('Error!'); + } else { + if (~resp.preferences.indexOf('PreAuthorization')) { + user.get({preferences:1}, {_id: query.id }, function (err, doc) { + console.log(doc); + if (err) { + console.log(err); + res.end('Error!'); + } else { + // res.json(resp); + doc.preferences.hasBudget = true; + doc.save(function(err){ + if (err) { + console.log(err); + res.end(); + } else { + res.json(resp); + } + }) + } + }); + } else { + var arr = resp.contract.asset.split('/'); + user.addPurchase(arr[arr.length-1], {'owner':'https://dev.payswarm.com/i/piatra'}, function (err) { + if (err) { + console.log('an error occured', err); + res.end('Error'); + } else { + res.json(resp); + } + }); + } + } + }) + }, + getUserAssets: function (req, res) { var query = { email: req.session.email }; console.log(query); @@ -339,6 +431,23 @@ var assets = { }); }, + preview: function (req, res) { + asset.getAsset({listingId: req.params.id}, function (doc) { + if (doc.error) + res.end('Asset not found'); + else { + doc.assetPreview = req.body.preview; + doc.save(function (err) { + if (err) { + res.end('An error has occured'); + } else { + res.redirect('/'); + } + }) + } + }) + }, + getLatestAssets: function (req, res) { asset.getUserAssets({}, function (assets) { res.json(assets); diff --git a/routes/assets/140110e6550 b/routes/assets/140110e6550 new file mode 100644 index 0000000..c7c72fb --- /dev/null +++ b/routes/assets/140110e6550 @@ -0,0 +1,114 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/140110e6550", + "listingId": "140110e6550", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "" + }, + "title": "mug", + "assetContent": "https://webpayments.fwd.wf/assets/asset/140110e6550", + "assetProvider": "https://dev.payswarm.com/i/webpayments", + "listingRestrictions": { + "validFrom": "2013-07-24T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/140110e6550/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "assetProvider" + ], + "payeeRate": "80", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively", + "payeeApplyGroup": [ + "vendor" + ], + "minimumAmount": "0.01", + "comment": "Asset Provider Royalty" + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ] + }, + { + "type": "PayeeRule", + "payeeGroup": [ + "vendor" + ], + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively" + } + ] + }, + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/webpayments/keys/3", + "created": "2013-07-24T14:21:30Z", + "signatureValue": "Cp2/KxRIiikk26hBEDRZhcscAxGfq8c7mr1cCj9UyEtbxFrk6r/RhJJpKUsRUiruit5ZiKkH33I3eJN82i5vSQQA3gCokYQkvGowoNwewjyOteqLlm9yW2CPYoPA631TFBfNoaNOJ2zV7dSTRitXSKf5xAjP4jaYfZrxwB2OJiEBytzuvi9UY9ITRrK+2recpb/JFkNtlGflMi5HnHvfBoMlQOxA1sxa1Oa1tXZ/k16wY1ghyioC90OCsqi+XbqOD+WeNojUHVZvnz9kiqQmvmacGSD/Hb1BNBSWxATxzrePfyMZoPmpQIa9YJ8brKBiv6WO2TlLgTgGs0GPOLscSA==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/140110e6550", + "assetId": "140110e6550", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/piatra", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/140110e6550/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "mug [140110e6550]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/140110e6550", + "assetHash": "urn:sha256:3b76b49d43bb74f22b02481bcef74d575b56aa1abd97516279a316247a4bf2cf", + "license": "https://w3id.org/payswarm/licenses/blogging", + "licenseHash": "urn:sha256:d9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9", + "validFrom": "2013-07-24T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/webpayments/keys/3", + "created": "2013-07-24T14:21:30Z", + "signatureValue": "bDln9qu+advujCZjX0sYT2LLMEVJfIaaOu+R+YENTToZzOAR6I8zCaFmdChl14izPhrSi5mkxVymOyD5uEfBmhOi2JvKvh9qsbI48dYC7NFNVDoeI8QpUHLMST/RkJDg8GpDKynTadETKS3wF7lhITeUqPaYgo7ntKFBYt60AFCDJsJl4NAyTDbsanif9vJ8dPFmsiH00RN+YsSuBj//tZSvV9jBFQp4eauC2cQ3GClpUT5kwTnSeK1vP3yiHXJNuyZezH95HhdUsTqGqdAogjfv9VAi+EKtnFBevE/r3ifsB9qgWFMPqUaDMyQ1pxO7EmaAupAnk27vKwhgdAO4gw==" + } + } + ] +} \ No newline at end of file diff --git a/routes/assets/14011124869 b/routes/assets/14011124869 new file mode 100644 index 0000000..3cba372 --- /dev/null +++ b/routes/assets/14011124869 @@ -0,0 +1,114 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/14011124869", + "listingId": "14011124869", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "" + }, + "title": "macbook", + "assetContent": "https://webpayments.fwd.wf/assets/asset/14011124869/content", + "assetProvider": "https://dev.payswarm.com/i/webpayments", + "listingRestrictions": { + "validFrom": "2013-07-24T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/14011124869/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "assetProvider" + ], + "payeeRate": "80", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively", + "payeeApplyGroup": [ + "vendor" + ], + "minimumAmount": "0.01", + "comment": "Asset Provider Royalty" + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ] + }, + { + "type": "PayeeRule", + "payeeGroup": [ + "vendor" + ], + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively" + } + ] + }, + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/webpayments/keys/3", + "created": "2013-07-24T14:25:45Z", + "signatureValue": "Cv0W0IdRWjSW46Jt+XHqxW9pJ1LcgpbyRALf3VgVNgeIV4x++L0yX4vSzDf+9CXDAyf31IBgWBU6ITZgKDAK+OwT9ujQfK4RSpuMPGNvwqpeCTncDCV5KPjA3d2/7bKktvPniMrdJI+lWkbq7VlvgBUfAj87tNkFeyso5vvdsHROmpNNRkYOXwbDCqDWYJyp/ubxs09ifcxpOYFH7D7HpxbUNm+WeGoAORzWLUUWvMaVCRhfJCjJkv8jAKyCD85ZQp6ak9Uj++rIadEaIuVKgM0wlGwPyU/OODXa9VQxxn6LUBvZADP3RZSvzaRjg/ZwUDAiFjgRCt51RHZnaOyR3w==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/14011124869", + "assetId": "14011124869", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/webpayments", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/14011124869/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "macbook [14011124869]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/14011124869", + "assetHash": "urn:sha256:97691080a7f2d1c4f699ce5f8878046a0ba8c6e0febd6a69e1939082522dcd81", + "license": "https://w3id.org/payswarm/licenses/blogging", + "licenseHash": "urn:sha256:d9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9", + "validFrom": "2013-07-24T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/webpayments/keys/3", + "created": "2013-07-24T14:25:45Z", + "signatureValue": "jSyQsyt6wgWJ4ErAtRBLgHbXYOaT8Cd/73mSSFt2TkdIVfRHrowsDpzYF82KeK4VwesJSrBgr7tpybaLbtS+AIGQgmi1oyS1vvWaGzYV83rXUf4P/nJNlHYVUXecazcQyZyd7QkbVvnfNLn3hzXvBbiSc+nvL+QBuSw2TZOvLt6wlKy7LEUQIY8NpU2/VTBXByXYBJEnCe+qOwVe3itcC8opNfrbPCiH7+0RVvvKEMwtMdIR2guJ2JdrMuPgFY8zadPihuQpMDKzpxZEtMidtGVEk6bZZeWtLkvR5/j1NsbGLBAEiHAco3ODMOsmvVfXNwrLsYk79KBQISR9fMVgJw==" + } + } + ] +} \ No newline at end of file diff --git a/routes/auth.js b/routes/auth.js index 710d56f..cf4ffc5 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -78,10 +78,12 @@ var auth = { console.log(err); } else { console.log('auth doc', doc); + // a lot of functionality depends on those names req.session.identity = doc.owner; req.session.username = doc.username; req.session.registered = doc.registered; req.session.publicKey = body.publicKey; + req.session.email = body.email; res.json(body); } }) diff --git a/routes/index.js b/routes/index.js index 3c67cd6..d837ca3 100644 --- a/routes/index.js +++ b/routes/index.js @@ -5,40 +5,37 @@ var title = 'WebPayments Marketplace'; var assets = require('../lib/asset.js')(); +var _ = require('underscore'); + +function options (req) { + var obj = { + title: title, + user: (req.session.email) ? req.session.email : null, + id: (req.session.userid) ? req.session.userid : null, + identity: (req.session.identity) ? req.session.identity: null, + registered: (req.session.registered) ? req.session.registered : null, + publicKey: (req.session.publicKey) ? req.session.publicKey : null, + email: (req.session.email) ? req.session.email : null, + username: (req.session.username) ? req.session.username : null, + env: process.env.NODE_ENV + }; + _.forEach(_.rest(_.toArray(arguments)), function (el) { + obj[el[0]] = el[1]; + }); + return obj; +} exports.index = function(req, res) { - console.log('serving index'); - console.log('getting all assets'); assets.getUserAssets({}, function (assets) { - console.log(assets); - res.render('index', { - title: title, - user: (req.session.email) ? req.session.email : null, - id: (req.session.userid) ? req.session.userid : null, - identity: (req.session.identity) ? req.session.identity: null, - registered: (req.session.registered) ? req.session.registered : null, - publicKey: (req.session.publicKey) ? req.session.publicKey : null, - assets: assets.slice(0,4) - }); + res.render('index', options(req, ['assets', assets])); }); }; exports.login = function (req, res) { - res.render('login', { - title: title + ' - login' - }) + res.render('login', options(req)); } exports.newasset = function(req, res) { - console.log('new asset', req.session.username); - res.render('newasset', { - title: 'Create an asset', - user : (req.session.email) ? req.session.email : null, - identity: (req.session.identity) ? req.session.identity: null, - id : (req.session.userid) ? req.session.userid : null, - username: (req.session.username) ? req.session.username : null, - registered: (req.session.registered) ? req.session.registered : null, - publicKey: (req.session.publicKey) ? req.session.publicKey : null - }); + res.render('newasset', options(req)); }; \ No newline at end of file diff --git a/test.js b/test.js deleted file mode 100644 index 8cad606..0000000 --- a/test.js +++ /dev/null @@ -1,33 +0,0 @@ -var fs = require('fs'); -console.log('reading'); -fs.readFile('./test.txt', 'utf8', function (err, data) { - console.log(err); - json = JSON.parse(data); - console.log(json); - _clone(json); -}); - -function _clone(value) { - if(value && typeof value === 'object') { - var rval; - console.log('going to test ', value); - if(_isArray(value)) { - rval = []; - for(var i = 0; i < value.length; ++i) { - rval[i] = _clone(value[i]); - } - } - else { - rval = {}; - for(var key in value) { - rval[key] = _clone(value[key]); - } - } - return rval; - } - return value; -} - -function _isArray(v) { - return Array.isArray(v); -} \ No newline at end of file diff --git a/views/asset-purchase.jade b/views/asset-purchase.jade new file mode 100644 index 0000000..19925a6 --- /dev/null +++ b/views/asset-purchase.jade @@ -0,0 +1,20 @@ +extends layout + +block content + .container + .well.padding5 + p: small: em= message + .container + + + + + + + + + + + + + diff --git a/views/index.jade b/views/index.jade index 7413875..16056a7 100644 --- a/views/index.jade +++ b/views/index.jade @@ -1,22 +1,29 @@ extends layout block content - .description - .container + .container + .well.padding5 h4 Welcome to the WebPayments Marketplace p: small: em This application is implemented using: Mozilla Persona, Payswarm.js - if (!user) p You should sign up for an account and give it a try + - else + p.bubble--info: small: em Unless you have an account set up with us all purchases will be made through the payswarm authority .container - br + hr .category - h4.category__title - | Newest - a.topcoat-button.pull-right(href='/assets/all') See all + ul.tab-bar + li.topcoat-button Newest + li.topcoat-button Popular ul.item-container.container--newest - - assets.forEach(function (asset) { + - assets.forEach(function (asset, i) { + - url = '/assets/asset/' + asset.asset.listingId + '/purchase'; li h4= asset.asset.title - p comment - a.topcoat-button--cta(href='/assets/' + asset.asset.listingId + '/purchase') Buy + - asset.asset.assetPreview.forEach(function (f) { + img(src='/uploads/' + asset.asset.listingId + '_' + f) + - }) + p= asset.listing.payee[0].comment + p= asset.listing.payee[0].payeeRate + ' ' + asset.listing.payee[0].currency + a.topcoat-button--cta.buy--cta(href=url) Buy - }) \ No newline at end of file diff --git a/views/layout.jade b/views/layout.jade index 9f317dd..a3e2ed3 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -7,14 +7,14 @@ html body .topcoat-navigation-bar .container - .topcoat-navigation-bar__item.left.quarter - a(class='topcoat-icon-button--quiet', href='/') Home - a(class='topcoat-icon-button--quiet', href='/newasset') Sell - a(class='topcoat-icon-button--quiet', href='/about') About - input(type='search', placeholder='search') + .topcoat-navigation-bar__item.left.quarter.tab-bar + li: a(class='topcoat-icon-button--quiet', href='/') Home + li: a(class='topcoat-icon-button--quiet', href='/newasset') Sell + li: a(class='topcoat-icon-button--quiet', href='/about') About + li: input.topcoat-search-input(type='search', placeholder='search') .topcoat-navigation-bar__item.center.half h1.topcoat-navigation-bar__title= title || 'WebPayments Marketplace' - .topcoat-navigation-bar__item.right + .topcoat-navigation-bar__item.right.quarter a.topcoat-icon-button--quiet - if (user) button.right(class='topcoat-icon-button', data-id=id) diff --git a/views/login.jade b/views/login.jade new file mode 100644 index 0000000..867433b --- /dev/null +++ b/views/login.jade @@ -0,0 +1,11 @@ +extends layout + +block content + .container + .well.padding5 + h2 Welcome to the WebPayments Marketplace + p.bubble--info In order to sell a product you need to login first. + p Login is handled through Mozilla Persona. You can read more about this + a(href='http://www.mozilla.org/en-US/persona/') here + |. + img(src='http://mozorg.cdn.mozilla.net/media/img/persona/signin.png') \ No newline at end of file diff --git a/views/newasset.jade b/views/newasset.jade index 7987860..9860c98 100644 --- a/views/newasset.jade +++ b/views/newasset.jade @@ -1,8 +1,8 @@ extends layout block content - .description - .container + .container + .well.padding5 - if (!username) h4 Choose a username p: small: em This is used to show who is selling the asset without showing your real email address. @@ -24,7 +24,7 @@ block content td: input(type='hidden', name='email', value=user) td: button(type='submit', class='topcoat-button--large--cta') Set username - if (username && registered != 'false') - form.half.pull-left.js-handler--create-asset(action='/newasset/process/', method='POST') + form.half.pull-left(class='js-handler--create-asset', action='/newasset/process/', method='POST', enctype='multipart/form-data') table.table-form tr td: input(type='hidden', value=user, name='email') @@ -38,8 +38,12 @@ block content td Description td: textarea(class='topcoat-textarea full-width', placeholder='Comments', name='description') tr - td: label Link to content - td: input(class='topcoat-text-input', type='file', name='assetContent',required) + td + td + p: em: small Select images and add them as content + p: em: small Add the assets you want to sell + input(class='topcoat-text-input', type='file', name='files', required, multiple) + p: em: small.js-handler--filesAttached tr td: label Price td @@ -65,8 +69,8 @@ block content p input(type='hidden', name='userId', value=id) input(type='hidden', name='owner', value=identity) - button(type='submit', class='topcoat-button--large--cta pull-right') Create asset - .half.pull-right.description.margin-top + input.buy--cta(type='submit', class='topcoat-button--large--cta') Create asset + .half.pull-right.padding5#preview h2 About assets and listings p An asset is a description of a product or service. Examples of assets include web pages, ebooks, groceries, concert tickets, dog walking services, donations, rights to transmit on a particular radio frequency band, and invoices for work performed. In general, anything of value can be modeled as an asset. p A listing is a description of the specific terms under which an asset is offered for sale. These terms include: the exact asset being sold, the license that will be associated with the purchase, the list of people or organizations to be paid for the asset, and the validity period for the listing. Like an asset, a listing may include other application-specific properties. diff --git a/views/preview-selection.jade b/views/preview-selection.jade new file mode 100644 index 0000000..c0df3e9 --- /dev/null +++ b/views/preview-selection.jade @@ -0,0 +1,16 @@ +extends layout + +block content + .container + .well.padding5 + p.bubble--info: small: em Your asset has been successfully created + p: small: em Please choose a preview for your product + .container + form(method='POST', action='/assets/asset/' + id + '/preview') + - files.forEach(function (f) { + p.inline-block + label= f.name + input(type='checkbox', name='preview', value=f.name) + img.max-width--200(src='/uploads/' + id + '_' + f.name) + - }) + p: input.topcoat-button--cta(type='submit', value='Done') \ No newline at end of file diff --git a/views/test.jade b/views/test.jade new file mode 100644 index 0000000..251db1c --- /dev/null +++ b/views/test.jade @@ -0,0 +1,6 @@ +extend layout + +block content + form(action="/upload", method="post", enctype="multipart/form-data") + input(type="file", name="displayImage") + button(type=submit) \ No newline at end of file