diff --git a/app.js b/app.js index 848c50f..dd635aa 100644 --- a/app.js +++ b/app.js @@ -8,6 +8,7 @@ var express = require('express') , assets = require('./routes/assets') , auth = require('./routes/auth') , http = require('http') + , user = require('./routes/user') , path = require('path'); var app = express(); @@ -32,19 +33,65 @@ 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); +app.post('/user/payswarm', auth.payswarmVerify); + app.get('/auth/createKeyPair', auth.createKeyPair); app.post('/payswarm/register', auth.registerKey); app.post('/payswarm/complete', auth.complatePayswarmRegistration); -app.get('/newasset', routes.newasset); -app.post('/newasset/process/', assets.processAsset); + +/* + New asset +*/ +app.get('/newasset', requireLogin, routes.newasset); +app.post('/newasset/process/', assets.createAssetAndListing); app.post('/newasset/save', assets.saveAsset); app.get('/assets/created', assets.getUserAssets); 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('/assets/asset/:id/content', function (req, res){ + res.end('The content!'); +}); + +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 8868e26..266a60f 100644 --- a/lib/asset.js +++ b/lib/asset.js @@ -6,7 +6,8 @@ var _ = require('underscore'), utils = require('../lib/utils')(), payswarm = require('payswarm'), mongoose = require('mongoose'), - db = require('../lib/db') + db = require(__dirname + '/db.js'), + host = 'webpayments.fwd.wf'; ; module.exports = function (options) { @@ -24,9 +25,6 @@ module.exports = function (options) { cb(err); } else { // set the asset to the listing - signedListing.asset = signedAsset.id; - signedListing.assetHash = assetHash; - signedListing.licenseHash = listingHash; var assetAndListing = { "@context": 'https://w3id.org/payswarm/v1', "@graph": [signedAsset, signedListing] @@ -136,6 +134,40 @@ module.exports = function (options) { db.save.asset(graph, cb); } + function getOne (query, cb) { + getOneAsset(query, function (asset) { + getOneListing({'assetId': query['_id']}, function (listing) { + var assetAndListing = { + "@context": 'https://w3id.org/payswarm/v1', + "@graph": [asset[0], listing[0]] + } + cb(assetAndListing); + }); + }); + } + + function getOneAsset (query, cb) { + db.get.asset(query, function (err, doc) { + if (err) { + console.log('Error getting one asset' + err); + cb(err, {}); + } else { + cb(null, doc); + } + }); + } + + function getOneListing (query, cb) { + db.get.listing(query, function (err, doc) { + if (err) { + console.log('Error getting one listing' + err); + cb({}); + } else { + cb(doc); + } + }); + } + function getUserAssets (query, cb) { db.get.userAssets(query, function (err, assets) { if (err) { @@ -144,8 +176,10 @@ module.exports = function (options) { } else { var docs = []; var l = assets.length; + console.log('found' + l + 'assets for query',query); + if(!l) cb(docs); assets.forEach(function (asset) { - db.get.userListings(asset['_id'], function (err, doc) { + db.get.listing({'assetId':asset.listingId}, function (err, doc) { if (err) { console.log(err); cb({'error':err}); @@ -164,10 +198,39 @@ module.exports = function (options) { }) } + function getListing (query, cb) { + console.log('query', arguments); + var errMsg = {'error': 'Listing not found'}; + db.get.listing(query, function (err, doc) { + if (err || !doc.length) { + console.log(err); + cb(errMsg); + } else { + cb(doc[0] || errMsg); + } + }); + } + + function getAsset (query, cb) { + var errMsg = {'error': 'Asset not found'}; + db.get.asset(query, function (err, doc) { + if (err || !doc.length) { + console.log(err); + cb(errMsg); + } else { + cb(doc[0] || errMsg); + } + }); + } + // sign is a facade for creating + signing assetUtils.sign = sign; assetUtils.save = saveAssetAndListing; assetUtils.getUserAssets = getUserAssets; + assetUtils.getOne = getOne; + assetUtils.getListing = getListing; + assetUtils.getAsset = getAsset; + assetUtils.getOneListing = getOneListing; return assetUtils; }; \ No newline at end of file diff --git a/lib/asset.simple.cfg b/lib/asset.simple.cfg index b1b6be2..3242c32 100644 --- a/lib/asset.simple.cfg +++ b/lib/asset.simple.cfg @@ -1,6 +1,7 @@ { "@context": "https://w3id.org/payswarm/v1", - "id": "http: //listings.dev.payswarm.com/mozhacks/demo#asset", + "id": "http://listings.dev.payswarm.com/mozhacks/demo#asset", + "userId": "~", "type": [ "Asset" ], @@ -8,6 +9,6 @@ "fullName": "DeveloperJoe" }, "title": "MozillaHacksDemoAsset", - "assetContent": "http: //listings.dev.payswarm.com/mozhacks/demo#asset", - "assetProvider": "https: //dev.payswarm.com/i/YOUR_IDENTITY_HERE" + "assetContent": "http://listings.dev.payswarm.com/mozhacks/demo#asset", + "assetProvider": "https://dev.payswarm.com/i/YOUR_IDENTITY_HERE" } \ No newline at end of file diff --git a/lib/db.js b/lib/db.js index 68c382f..57228a0 100644 --- a/lib/db.js +++ b/lib/db.js @@ -1,12 +1,23 @@ var mongoose = require('mongoose'); +var _ = require('underscore'); if (process.env.NODE_ENV) var db = mongoose.connect('mongodb://nodejitsu:c0a886dafe2c7d59cfc1d0d62e61ebff@dharma.mongohq.com:10074/nodejitsudb4747069906'); -else - var db = mongoose.connect('mongodb://localhost:27017/webpayments'); +else { + console.log('localhost'); + var db = mongoose.connect('mongodb://localhost:27017/webpay'); +} var schemas = require('./schemas')(db); +function assert() { + argv = _.toArray(arguments); + if(!argv[0]) { + console.log(argv[2]); + throw new Error('Expected ' + argv[1] + ' to be defined'); + } +} + var dbUtils = { find: function (schema, query, fields, cb) { if (typeof fields === 'function') { @@ -26,21 +37,28 @@ var dbUtils = { } }, save : { - asset : function (graph, cb) { - var listing = new schemas.Listing(graph.listing); - console.log(graph.asset); - var asset = new schemas.Asset(graph.asset); + asset: function (assetAndListing, cb) { + + console.log(arguments); - asset.save(function (err, d) { - if (err) cb(err); - else { - listing.assetId = d['_id']; + var asset = new schemas.Asset(assetAndListing['@graph'][0]); + var listing = new schemas.Listing(assetAndListing['@graph'][1]); + + asset.save(function (err) { + console.log('asset err', err); + if (err) { + cb(err); + } else { listing.save(function (err) { - if (err) cb(err); - else cb(null); + console.log('listing err', err); + if (err) { + cb(err); + } else { + cb(null); + } }) } - }); + }) } }, findOne: { @@ -67,21 +85,14 @@ var dbUtils = { user: function (fields, user, cb) { schemas.User.findOne(user, fields, dbUtils.next(cb)); }, + asset: function (query, cb) { + schemas.Asset.find(query, dbUtils.next(cb)); + }, + listing: function (query, cb) { + schemas.Listing.find(query, dbUtils.next(cb)); + }, userAssets: function (query, cb) { - dbUtils.get.user({ - owner: 1 - }, query, function (err, doc) { - if (err) { - console.log(err); - cb(err); - } else { - console.log(doc); - console.log(query); - schemas.Asset.find({ - assetProvider: doc.owner - }, dbUtils.next(cb)); - } - }) + schemas.Asset.find(query, dbUtils.next(cb)); }, userListings: function (id, cb) { dbUtils.find(schemas.Listing, {assetId: id}, dbUtils.next(cb)); diff --git a/lib/keys.js b/lib/keys.js index b782615..7945e75 100644 --- a/lib/keys.js +++ b/lib/keys.js @@ -17,7 +17,7 @@ module.exports = function(opts) { console.log('Error reading keys: ', err); } else { keyPair = JSON.parse(data); - payswarm.decrypt(encryptedMessage, {privateKey: keyPair.privateKeyPem}, cb); + payswarm.decrypt(encryptedMessage, {privateKey: keyPair.publicKey.privateKeyPem}, cb); } }); } diff --git a/lib/listing b/lib/listing new file mode 100644 index 0000000..72647ab --- /dev/null +++ b/lib/listing @@ -0,0 +1,30 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "id": "http://listings.dev.payswarm.com/mozhacks/html5-me-song#listing", + "userId": "~", + "type": ["Listing"], + "vendor": "https://dev.payswarm.com/i/the-webdevs", + "payee": [{ + "type": "Payee", + "destination": "https://dev.payswarm.com/i/the-webdevs/accounts/royalties", + "payeeGroup": ["vendor"], + "payeeRateType": "FlatAmount", + "payeeRate": "1.00", + "currency": "USD", + "payeeApplyType": "ApplyExclusively", + "comment": "Payment to The Webdevs for creating the HTML5 Me, Baby song" + }], + "payeeRule": [{ + "type": "PayeeRule", + "payeeGroupPrefix": ["authority"], + "payeeRateType": "Percentage", + "maximumPayeeRate": "5", + "payeeApplyType": "ApplyInclusively" + }], + "asset": "http://listings.dev.payswarm.com/mozhacks/html5-me-song#asset", + "assetHash": "assetHash", + "license": "https://w3id.org/payswarm/licenses/personal-use", + "licenseHash": "urn:sha256:d9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9", + "validFrom": "date", + "validUntil": "date" +} \ No newline at end of file diff --git a/lib/listing.simple.cfg b/lib/listing.simple.cfg index 2def8f1..755765c 100644 --- a/lib/listing.simple.cfg +++ b/lib/listing.simple.cfg @@ -1,11 +1,12 @@ { "@context": "https://w3id.org/payswarm/v1", "id": "http://listings.dev.payswarm.com/mozhacks/html5-me-song#listing", + "userId": "~", "type": ["Listing"], - "vendor": "https://dev.payswarm.com/i/the-webdevs", + "vendor": "https://dev.payswarm.com/i/webpayments", "payee": [{ "type": "Payee", - "destination": "https://dev.payswarm.com/i/the-webdevs/accounts/royalties", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/primary", "payeeGroup": ["vendor"], "payeeRateType": "FlatAmount", "payeeRate": "1.00", @@ -22,8 +23,13 @@ }], "asset": "http://listings.dev.payswarm.com/mozhacks/html5-me-song#asset", "assetHash": "assetHash", + "listing": "listing", "license": "https://w3id.org/payswarm/licenses/personal-use", "licenseHash": "urn:sha256:d9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9", + "listingHash": "whatev", + "nonce":"123123123", + "transactionId":"123789", "validFrom": "date", - "validUntil": "date" + "validUntil": "date", + "identity":"1" } \ No newline at end of file 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/ref b/lib/ref new file mode 100644 index 0000000..4b1a27b --- /dev/null +++ b/lib/ref @@ -0,0 +1,3 @@ +Public Key Owner : https://dev.payswarm.com/i/piatra + Financial Account: https://dev.payswarm.com/i/piatra/accounts/primary + Public Key URL : https://dev.payswarm.com/i/piatra/keys/30 diff --git a/lib/schemas.js b/lib/schemas.js index c28322a..1f19c8e 100644 --- a/lib/schemas.js +++ b/lib/schemas.js @@ -9,46 +9,77 @@ var UserSchema = new Schema({ }, publicKeyUrl : String, owner : String, - destination : String + destination : String, + username: String, + preferences: { + hasBudget: Boolean + }, + purchases: [String] }); +var PayeeSchema = { + id: String, + type: 'Payee', + destination: String, + currency: String, + payeeGroup: [String], + payeeRate: Number, + payeeRateType: 'Percentage', + payeeApplyType: 'ApplyInclusively', + payeeApplyGroup: [String], + minimumAmount: Number, + comment: String +}; + var AssetSchema = { + "@context": String, id: String, + listingId: String, type: Array, creator: { - fullName: String + fullName: String, + userId: String }, title: String, assetContent: String, + assetFiles: [String], + assetPreview: [String], assetProvider: String, - signature : Object + signature : Object, + assetDescription: String, + listingRestrictions: { + validFrom: String, + validUntil: String, + payee: Object, + payeeRule: Object + } }; + var ListingSchema = { + "@context": String, id: String, - assetId: Schema.Types.ObjectId, + assetId: String, + userId: String, type: Array, vendor: String, payee: Array, payeeRule: Array, asset: String, assetHash: String, + _listingHash: String, license: String, licenseHash: String, - validFrom: Date, - validUntil: Date, + validFrom: String, + validUntil: String, signature: Object } module.exports = function (db) { var schemes = {}; - var Listing = mongoose.model('Listing', ListingSchema); - var Asset = mongoose.model('Asset', AssetSchema); - var User = mongoose.model('User', UserSchema); + schemes.Listing = mongoose.model('Listing', ListingSchema); + schemes.Asset = mongoose.model('Asset', AssetSchema); + schemes.User = mongoose.model('User', UserSchema); - return { - Listing: Listing, - Asset: Asset, - User: User - }; + return schemes; } \ No newline at end of file diff --git a/lib/user.js b/lib/user.js index 229338d..045f7a8 100644 --- a/lib/user.js +++ b/lib/user.js @@ -5,7 +5,6 @@ module.exports = function (opts) { var userUtils = {}; function checkUser (json, cb) { - console.log(db); db.findOne.user({email : json.email}, cb); } @@ -17,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/output b/output new file mode 100644 index 0000000..ad0a981 --- /dev/null +++ b/output @@ -0,0 +1,129 @@ +Generating asset... +Signing asset... +Generating and signing listing... +Register signed asset and listing... +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/1400b472708", + "listingId": "1400b472708", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "51e96cc8a0e24c65b0000001" + }, + "title": "keon", + "assetContent": "https://webpayments.fwd.wf/assets/asset/1400b472708", + "assetProvider": "https://dev.payswarm.com/i/piatra", + "listingRestrictions": { + "validFrom": "2013-07-23T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/1400b472708/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-23T11:25:47Z", + "signatureValue": "MRwAkVIBlIbJPNnGd/+Mv6Ov5ywguRtATVEcMk71tsWPP62bQXT/EnpcDlOZPvVdRlFoXCCVKtJ+o6t5BE2zA4ko8De1CmwdE6bFidSVWpiPOIL+CEcOFCS9DbqO/zScLdHyu/KZZ4+PMm/2aaKK9Ucm4Tn0peAqVgIufHOwyPdVRqz1f+jrTmRKDYfLjYa8ZlfLIOXNRmu8z23/fClqOUM77L8CKDYnHDBe/vGulQ8fsykkW+CCD/7EkoS9MOL/z5EaFUAiVcfVFKRfpxcAJ/PmuxwLksbeW9WweHA1g3aGcEZSYJDMXbHmvILtgIu0GG5EwlNYfExSfCrUNjwW9Q==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/1400b472708", + "assetId": "1400b472708", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/piatra", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/1400b472708/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "keon [1400b472708]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/1400b472708", + "assetHash": "urn:sha256:51331ea635cb74fc926da88cabede966c3705c7b62c7a4be25e2237bd9d5344e", + "license": "https://w3id.org/payswarm/licenses/blogging", + "licenseHash": "urn:sha256:d9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9", + "validFrom": "2013-07-23T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/webpayments/keys/3", + "created": "2013-07-23T11:25:47Z", + "signatureValue": "P3YSr1mHxMBaUDpy4VxzqZKeeT+DJd5PPzv1JFAOpHxwfa4QkjFjv73KriDrTkFvsTtNInxlMi1p2TDNXl79w4hz5sufuqSmC11gMVn65VFcRBdCogW94a7LYIPif3EEXMmSeGkvsOSUqmN/ia5DzfoFB6AfQApqa0xyNr6wQCswqi6DctVrLkox5HcpzT+kwrlEgXzWWI22QeFtcP0jsE8Mr8+8x2HfitRdsnKxQ+3jZe6ECF6L5x+IdCYVqRXgoBM01sFq6yimkIRl5nmF+cWEV8eIAjyAMz1xJ44nvznn9/ajUp9JKqfC4yso0GpRQiTImiJ4qNBgRHGg61FO5A==" + } + } + ] +} +{ '0': + { '@context': 'https://w3id.org/payswarm/v1', + '@graph': [ [Object], [Object] ] }, + '1': [Function] } +asset err null +listing err null +Registered signed asset: + https://webpayments.fwd.wf/assets/asset/1400b472708 +Registered signed listing: + https://webpayments.fwd.wf/listings/listing/1400b472708 +23 Jul 14:25:49 - [nodemon] exiting diff --git a/package.json b/package.json index c6ae45a..1c85aa4 100644 --- a/package.json +++ b/package.json @@ -21,13 +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" + }, "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 0000000..ae82378 Binary files /dev/null and b/public/images/bg-gradient-sand.png differ diff --git a/public/images/bg-sand.png b/public/images/bg-sand.png new file mode 100644 index 0000000..6b2d79d Binary files /dev/null and b/public/images/bg-sand.png differ diff --git a/public/images/payswarm.png b/public/images/payswarm.png new file mode 100644 index 0000000..a1ed6a1 Binary files /dev/null and b/public/images/payswarm.png differ diff --git a/public/javascripts/event-assets.js b/public/javascripts/event-assets.js index 093c403..1906e9a 100644 --- a/public/javascripts/event-assets.js +++ b/public/javascripts/event-assets.js @@ -4,22 +4,29 @@ define(['modal', 'message'], function (modal, message) { console.log('asset created'); modal.show({ title: 'Asset and listing', - components : [ - { - tag: 'pre', - class: 'container--json', - html: JSON.stringify(response, null, 4) - }, - { - tag: 'input', type:'submit', - value: 'Publish', - class: 'topcoat-button--large--cta pull-right js-handler--publish-asset', - } - ], - form: '/newasset/save' + components : [{ + tag: 'p', + text: 'You asset and listing have been created and publised', + }] }).appendTo('body'); - $('.js-handler--publish-asset').on('click', assets.publish); + $('.close-handler').on('click', function () { + location.href = '/'; + }); + } + + function usernameChanged (response) { + modal.show({ + title: 'Your username has been set', + components : [{ + tag: 'p', + text: 'Congrats you now have a username!', + }] + }).appendTo('body'); + + $('.close-handler').on('click', function () { + location.href = '/newasset'; + }); } function setAssetCount (count) { @@ -42,7 +49,7 @@ define(['modal', 'message'], function (modal, message) { function setListAssets (docs) { docs.forEach(function (d) { - if (!d.listing) return; + if (!d.listing.payee[0]) return; var title = d.asset.title + '
' + d.listing.payee[0].comment + ''; $('
  • ').addClass('topcoat-list__item') .html(title).appendTo('.js-handler--asset-list'); @@ -50,14 +57,18 @@ define(['modal', 'message'], function (modal, message) { } var assets = { - create: function (e) { - e.preventDefault(); - var data = $('form').serialize(); - $.post($('form').attr('action'), data) - .done(assetCreated) - .fail(errorHandler) - ; - + // handler: .js-handler--create-asset + // on : submit + // action : /newasset/process/ + create: function (cb) { + return function (e) { + e.preventDefault(); + var data = $('form').serialize(); + $.post($('form').attr('action'), data) + .done(cb) + .fail(errorHandler) + ; + } }, publish: function (e) { var json = JSON.parse($('.container--json').text()); @@ -85,7 +96,9 @@ define(['modal', 'message'], function (modal, message) { }) .fail(errorHandler) ; - } + }, + usernameChanged: usernameChanged, + assetCreated: assetCreated } return assets; diff --git a/public/javascripts/event-handlers.js b/public/javascripts/event-handlers.js index c7927ca..a92ba5d 100644 --- a/public/javascripts/event-handlers.js +++ b/public/javascripts/event-handlers.js @@ -1,15 +1,19 @@ 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) { $.post("/auth/verify", { assertion: assertion }) - .success(loginEv.handleLogin).fail(function (data) { - console.log('fail', data); - }); + .success(loginEv.handleLogin) + .fail(function (data) { + console.log('fail', data); + }) + ; } }; @@ -17,12 +21,10 @@ define([ init : function () { var email = ($('img', $('.js-handler--login')).length) - ? null - : $('.js-handler--login').text().trim() + ? null + : $('.js-handler--login').text().trim() ; - console.log(email); - navigator.id.watch({ onlogin: function(assertion) { if ($('img', $('.js-handler--login')).length) @@ -40,7 +42,18 @@ define([ navigator.id.request(); }); - $('.js-handler--create-asset').on('submit', assetsEv.create); + // $('.js-handler--create-asset').on('submit', assetsEv.create(assetsEv.assetCreated)); + + $('.js-handler--change-username').on('submit', assetsEv.create(assetsEv.usernameChanged)); + + // FIXME + if ($('.js-handler--show-payswarm-verify').length) { + $.post('/payswarm/register/', { + publicKey: $('.js-handler--show-payswarm-verify').text() + }).success(loginEv.displayPayswarmMsg); + } + + //$('input[type=file]').on('change', upload.sendFile); assetsEv.loadLatest($('.container--newest')); diff --git a/public/javascripts/event-login.js b/public/javascripts/event-login.js index 8f20cb6..7ecc3f9 100644 --- a/public/javascripts/event-login.js +++ b/public/javascripts/event-login.js @@ -15,15 +15,16 @@ define(['message', 'modal'], function (message, modal) { showPayswarmRegistration : function (response) { $.post('/payswarm/register/', { publicKey : response.publicKey - }).success(function (href) { - var msg = message.show({ - message : 'You need to register with a payswarm authority', - href : href, - appendTo : '.messages', - newTab : true - }); - loginEv.completePayswarmRegistration(msg); + }).success(loginEv.displayPayswarmMsg); + }, + displayPayswarmMsg: function (href) { + var msg = message.show({ + message : 'You need to register with a payswarm authority', + href : href, + appendTo : '.messages', + newTab : true }); + loginEv.completePayswarmRegistration(msg); }, completePayswarmRegistration : function (msg) { $('a', msg).on('click', function () { @@ -31,11 +32,11 @@ define(['message', 'modal'], function (message, modal) { title: 'Complete Payswarm registration', components : [ {tag: 'textarea', placeholder: 'Paste the content here', name: 'payswarm_response'}, - {tag: 'input', type: 'hidden', name: 'email', value: $('.js-handler--login').text()}, + {tag: 'input', type: 'hidden', name: 'email', value: $('.js-handler--email').text()}, {tag: 'input', type:'submit', value: 'Register', 'class' : 'button--main'} ], form: '/payswarm/complete' - }) + }).appendTo('body'); }); } } diff --git a/public/javascripts/test.txt b/public/javascripts/test.txt new file mode 100644 index 0000000..b9c43b4 --- /dev/null +++ b/public/javascripts/test.txt @@ -0,0 +1,49 @@ +{ + "assetId": "51e5bbb32accfe6525000002", + "@context": "https://w3id.org/payswarm/v1", + "id": "http://listings.dev.payswarm.com/mozhacks/html5-me-song#listing", + "userId": "51cb00e7b544338396000001", + "vendor": "https://dev.payswarm.com/i/the-webdevs", + "asset": "http://listings.dev.payswarm.com/mozhacks/demo#asset", + "assetHash": "urn:sha256:04a349226b8aa3342d1f793572e3a3049c539144d1762547862f92b44c084af9", + "license": "https://w3id.org/payswarm/licenses/personal-use", + "licenseHash": "urn:sha256:73ebeac3656bf37419a02a9d5041226dcc42722d5256895d324519a7b6d7d690", + "validFrom": "2013-07-16T00:00:00.000Z", + "validUntil": "2013-07-21T00:00:00.000Z", + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/authority/keys/1", + "created": "2013-07-16T21:31:29Z", + "signatureValue": "kv/uWVEhEbzig5LmBxAWqvShDM6GOiCL/8pXVG58N34VPmv6TPO8sHU1CEyg2PtL7UGdrRzJlj3gsWC7puyRPMt6SptU6VvFkXO8nP0unDFGUKOn1RfAzxgrMG9oxas/o/K+r6selfpKTygfYmdF+4aNDjh78bn3WwhJO4Wees+jH/5PDEY88dDdSw+c/ECkg4FPiMGQMzyG4TZwIu+AO2tNKSbicm44DJRbLYij+VeITbCJ/1R+LZlrJukKLqFTA/Km+3l7Tay100/xXvyCCzNCYf/LHwDCeBL7oiey9dx4YZYrtt/wQLUvNHI8jEIabjwCydz5I5DYKIOfwAVqXA==" + }, + "_id": "51e5bbb32accfe6525000001", + "__v": 0, + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "payeeRateType": "Percentage", + "maximumPayeeRate": "5", + "payeeApplyType": "ApplyInclusively" + } + ], + "payee": [ + { + "type": "Payee", + "destination": "https://dev.payswarm.com/i/the-webdevs/accounts/royalties", + "payeeGroup": [ + "vendor" + ], + "payeeRateType": "FlatAmount", + "payeeRate": "2", + "currency": "USD United States Dollars", + "payeeApplyType": "ApplyExclusively", + "comment": "this is a comment" + } + ], + "type": [ + "Listing" + ] +} \ No newline at end of file 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 65acc9e..d5dc70d 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -11,13 +11,14 @@ 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; text-decoration: none; } .container { - width: 90%; + width: 80%; margin: 0 auto; } .item-container { @@ -31,29 +32,32 @@ a { padding: 0; } .item-container li { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 3rem 0; padding: 1rem; height: 150px; - width: 20%; + width: 25%; list-style: none; - -webkit-flex: auto; - flex: 1 1 auto; - -webkit-transition-duration: 0.3s; - border-bottom: 4px solid #dfe2e2; -} -.item-container li:hover { - border-bottom: 4px solid #fff; + 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; - border-radius: 10px; } .messages { position: absolute; @@ -124,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; @@ -163,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; @@ -172,6 +188,29 @@ table td { .warning { background: #ffffbf; } +.full-width { + width: 100%; +} +.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; +} +.description { + background: #fff; + padding: 1rem; + border-bottom: 1px solid rgba(0,0,0,0.2); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} .docNav { font-size: 1rem; height: 3rem; @@ -221,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 04a9fe6..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,13 +13,14 @@ 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 text-decoration none .container - width 90% + width 80% margin 0 auto .item-container @@ -30,33 +31,41 @@ a -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; - padding 0 + padding 0; li + -webkit-box-sizing border-box + -moz-box-sizing border-box + box-sizing border-box + margin 3rem 0 padding 1rem height 150px - width 20% + width 25% list-style none - -webkit-flex: auto - flex: 1 1 auto; - -webkit-transition-duration .3s - border-bottom 4px solid #dfe2e2 - &:hover - border-bottom 4px solid #fff - -.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 - border-radius 10px .messages position absolute @@ -126,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 @@ -161,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 @@ -170,6 +191,29 @@ table th, table td .warning background warningBg +.full-width + width 100% + +.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 + +.description + background white + padding 1rem + border-bottom 1px solid rgba(0,0,0,.2) + -webkit-box-sizing border-box + -moz-box-sizing border-box + box-sizing border-box + .docNav font-size 1rem height 3rem @@ -218,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 8ec722e..b4762f7 100644 --- a/public/stylesheets/topcoat-mobile-light.css +++ b/public/stylesheets/topcoat-mobile-light.css @@ -687,10 +687,9 @@ Navigation Bar background: transparent; border: none; cursor: default; - height: 2.6rem; + 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); @@ -712,7 +711,7 @@ Navigation Bar background: transparent; border: none; margin: var-margin; - line-height: 2.6rem; + line-height: 5rem; vertical-align: top; } .topcoat-navigation-bar__title { @@ -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 { @@ -936,11 +920,11 @@ limitations under the License. -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; - padding: 0 1.25rem; + padding: 0 1rem; -webkit-border-radius: 6px; border-radius: 6px; margin: 5px; - height: 3rem; + height: 2rem; font: inherit; font-weight: 200; outline: none; @@ -1043,7 +1027,25 @@ Topcoat Large Textarea */ .topcoat-textarea--large { - font: var-font--large; + 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 54193d0..7ae746b 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -1,6 +1,202 @@ 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 = { + + createAssetAndListing: function (req, res) { + 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) { + if(err) { + console.log('Error: Failed to find a PaySwarm configuration file.'); + return callback(err); + } + k = JSON.parse(keysPair); + callback(null, k); + }); + }, + function(keysPair, callback) { + // Step #1: Create the asset and digitally sign it + console.log("Generating asset..."); + var assetUrl = HOST + '/assets/asset/' + assetId; + var asset = { + '@context': payswarm.CONTEXT_URL, + id: assetUrl, + listingId: assetId, + type: ['Asset', 'pto:WebPage'], + creator: { + fullName: req.body.email, + userId: req.body.userId + }, + title: req.body.title, + 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)), + payee: [{ + id: assetUrl + '/payee', + type: 'Payee', + destination: req.body.source, + currency: 'USD', + payeeGroup: ['assetProvider'], + destination: 'https://dev.payswarm.com/i/webpay/accounts/primary', + 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' + }] + } + }; + + // sign the asset + payswarm.sign(asset, { + publicKeyId: keysPair.publicKey.id, + privateKeyPem: keysPair.publicKey.privateKeyPem + }, callback); + }, + function(signedAsset, callback) { + // generate a hash for the signed asset + console.log("Signing asset..."); + payswarm.hash(signedAsset, function(err, assetHash) { + callback(err, signedAsset, assetHash); + }); + }, + function(signedAsset, assetHash, callback) { + // Step #2: Create and digitally sign the listing + console.log('Generating and signing listing...'); + var listingUrl = HOST + '/listings/listing/' + assetId; + var assetUrl = HOST + '/assets/asset/' + assetId; + + var listing = { + '@context': payswarm.CONTEXT_URL, + id: listingUrl, + assetId: assetId, + type: ['Listing', 'gr:Offering'], + vendor: 'https://dev.payswarm.com/i/webpay', + payee: [{ + id: listingUrl + '/payee', + type: 'Payee', + 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 + }], + payeeRule : [{ + type: 'PayeeRule', + payeeGroupPrefix: ['authority'], + maximumPayeeRate: '10', + payeeRateType: 'Percentage', + payeeApplyType: 'ApplyInclusively' + }], + asset: assetUrl, + assetHash: assetHash, + license: 'https://w3id.org/payswarm/licenses/blogging', + licenseHash: 'urn:sha256:' + + 'd9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9', + validFrom: payswarm.w3cDate(new Date(req.body.validFrom)), + validUntil: payswarm.w3cDate(new Date(req.body.validUntil)) + }; + + // sign the listing + payswarm.sign(listing, { + publicKeyId: k.publicKey.id, + privateKeyPem: k.publicKey.privateKeyPem + }, function(err, signedListing) { + callback(err, signedAsset, signedListing); + }); + }, + function(signedAsset, signedListing, callback) { + // Step #3: Register the signed asset and listing + console.log("Register signed asset and listing..."); + var assetAndListing = { + '@context': payswarm.CONTEXT_URL, + '@graph': [signedAsset, signedListing] + }; + + console.log(JSON.stringify(assetAndListing, null, 2)); + + asset.save(assetAndListing, function(err, result) { + callback(err, assetAndListing); + }); + }, + function(assetAndListing, callback) { + // display registration details + var debug = 0; + if(debug) { + console.log('Registered signed asset and listing: ' + + JSON.stringify(assetAndListing, null, 2)); + } + else { + console.log('Registered signed asset:\n ', + assetAndListing['@graph'][0].id); + console.log('Registered signed listing:\n ', + assetAndListing['@graph'][1].id); + } + callback(null); + } + ], function(err) { + if(err) { + console.log('Failed to register signed asset and listing:', + err.toString()); + } else { + res.render('preview-selection.jade', { + 'title': 'WebPayments Marketplace', + 'files': req.files.files, + 'id': assetId + }); + } + }); + }, + processAsset : function (req, res) { asset.sign(req, function (err, asset, listing) { @@ -40,19 +236,220 @@ var assets = { }); }, + purchase: function (req, res) { + // this is a big FIXME + 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) { + var query = {'assetId': req.params.id}; + asset.getListing(query, function (doc) { + res.json(doc); + }); + }, + + getAsset: function (req, res) { + var query = {'listingId': req.params.id}; + asset.getAsset(query, function (doc) { + res.json(doc); + }); + }, + + decrypt: function (req, res) { + var type = req.params.type, + query = {'_id': req.params.id} + ; + if (type == 'asset') { + asset.getAsset(query, function (doc) { + keys.getKeyPair(function (err, keys) { + var json = JSON.parse(keys); + payswarm.decrypt(doc, {privateKey: json.publicKey.privateKeyPem}, function (err, resp){ + res.json({ + err: err, + res: resp + }) + }); + }); + }); + } + if (type == 'listing') { + asset.getListing(query, function (doc) { + keys.getKeyPair(function (err, keys) { + var json = JSON.parse(keys); + payswarm.decrypt(doc, {privateKey: json.publicKey.privateKeyPem}, function (err, resp){ + res.json({ + err: err, + res: resp + }) + }); + }) + }); + } + }, + + resignListing: function (req, res) { + var query = {'_id' : req.params.id}; + asset.getListing(query, function (doc) { + keys.getKeyPair(function (err, keys) { + var keys = JSON.parse(keys); + doc.signature = {}; + var listing = { + '@context': payswarm.CONTEXT_URL, + id: doc.id, + type: ['Listing', 'gr:Offering'], + vendor: doc.vendor, + payee: doc.payee, + payeeRule : doc.payeeRule, + asset: doc.asset, + assetHash: doc.assetHash, + license: 'https://w3id.org/payswarm/licenses/blogging', + licenseHash: 'urn:sha256:' + + 'd9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9', + validFrom: doc.validFrom, + validUntil: doc.validUntil + }; + payswarm.sign(listing, { + publicKeyId: keys.publicKey.id, + privateKeyPem: keys.publicKey.privateKeyPem + }, function(err, signedListing) { + console.log(err, signedListing); + }); + }) + }); + }, + + 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', query, 'getUserAssets'); + console.log(query); asset.getUserAssets(query, function (assets) { - console.log('got assets', assets); res.json(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) { - console.log('limit', req.params.count); asset.getUserAssets({}, function (assets) { - console.log('getlatestassets', assets); res.json(assets); }); } diff --git a/routes/assets/1400bca6fe7 b/routes/assets/1400bca6fe7 new file mode 100644 index 0000000..49fcecf --- /dev/null +++ b/routes/assets/1400bca6fe7 @@ -0,0 +1,114 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/1400bca6fe7", + "listingId": "1400bca6fe7", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "51e96cc8a0e24c65b0000001" + }, + "title": "keon", + "assetContent": "https://webpayments.fwd.wf/assets/asset/1400bca6fe7", + "assetProvider": "https://dev.payswarm.com/i/piatra", + "listingRestrictions": { + "validFrom": "2013-07-23T00:00:00Z", + "validUntil": "2013-07-27T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/1400bca6fe7/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-23T13:49:11Z", + "signatureValue": "DQ1xgEquniPLxgv96Yizqm/H+AZdCk0IubU1d4esmJwBdrJczMXW9FXsuVgu69SCgIXlXw5N95DiVGpjg9jHBanKmCf11J0Gzn/JGq/3xX3QTd38a0pNpanuRBVgcqvdGEwX+HVWeT1UirJKMWWBR8NlrhQf9iwewr5Ltp3V6ZEX5MrA9fbXm9LVo1XBOJtjnkYORpqbHuuqhfS9thRGzIzInwsuUbNskuTGzEbQyrdjpeAMaK2ZB2tr3XbzE42sfTUeKUnmFWSVdC8sKnxE8OmFOOdqQD462WcSmV1qPbtMt++GuRBUg2PLGQHxgrVR7+Sc1SEaB9GUm4zRLD8aYg==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/1400bca6fe7", + "assetId": "1400bca6fe7", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/piatra", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/1400bca6fe7/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "keon [1400bca6fe7]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/1400bca6fe7", + "assetHash": "urn:sha256:0b5fde2dda58fd5e97c7c8a8c4f4b0f8086d0ca63cdf4266dfd68f95724d0315", + "license": "https://w3id.org/payswarm/licenses/blogging", + "licenseHash": "urn:sha256:d9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9", + "validFrom": "2013-07-23T00:00:00Z", + "validUntil": "2013-07-27T00:00:00Z", + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/webpayments/keys/3", + "created": "2013-07-23T13:49:11Z", + "signatureValue": "Lgx4zT4ejBRTNX2OKln12J8Ob8DtJVSx9xPa0lCgRZ5j9OKee2zz047SYNPejYkzxvpP+YPTIe/RWiZKCDHeM410dXnNlag/tWxc5YoMtNDJJJzrZnYwUBUkZuGLxP/ZPNQQEpizOlWUCk6Hkx0CPygdqEvO2eHi2JXfZ4TZFwoDl+HR+b3TA575TWILOiIPThi7kJAUbUnGNH+zGgIuc648HZYQLr7G60ZZHvAWlQgCFtOU8h+EJvrp2XpfwhWsECJV4Eqm89xWCZcaKktgcLzuwxErDthi2LGoPULuj1UH45SIrdEkgezBXH5bF6SmV/IbVEypEPyYOZCJgoyPjw==" + } + } + ] +} \ No newline at end of file diff --git a/routes/assets/1400bdcfa36 b/routes/assets/1400bdcfa36 new file mode 100644 index 0000000..4c91361 --- /dev/null +++ b/routes/assets/1400bdcfa36 @@ -0,0 +1,114 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/1400bdcfa36", + "listingId": "1400bdcfa36", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "51e96cc8a0e24c65b0000001" + }, + "title": "keon", + "assetContent": "https://webpayments.fwd.wf/assets/asset/1400bdcfa36", + "assetProvider": "https://dev.payswarm.com/i/piatra", + "listingRestrictions": { + "validFrom": "2013-07-23T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/1400bdcfa36/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-23T14:09:26Z", + "signatureValue": "b43ZDG2J9C9VRwCR9JCKUTeczxh3tAVHka10gLc6Sz7PK18PjZUezIKVrh6dMha209Ctq/iiMJyVzXcQHQseePOlDT2DJe8LdXd34EARXvttNC+o3uynBlDFCnwYFxFuM3JSRGH1hfhrVc0VAdSsj8W8962oQuNbPTw7xoxthU6z9q1R5Iu1inlCP44XUugsozTF5SquZg8xidfJTD/35zdBNf7nWo9yqpWc926sp+H7eyVpJJq5gBy10j0+N4DVSozOgaPy9i7UX245tfwV5fUKdUosqSC7QE8JvwjQVZWAWM+Vg2Qe8t7l7Px8qGzxS/VHP5/8+sRJiXlBDPcgZQ==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/1400bdcfa36", + "assetId": "1400bdcfa36", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/piatra", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/1400bdcfa36/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "keon [1400bdcfa36]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/1400bdcfa36", + "assetHash": "urn:sha256:9e4b373e9faa551fedf732345965692c0895be49a96dd0e09c53d74f1ab05910", + "license": "https://w3id.org/payswarm/licenses/blogging", + "licenseHash": "urn:sha256:d9dcfb7b3ba057df52b99f777747e8fe0fc598a3bb364e3d3eb529f90d58e1b9", + "validFrom": "2013-07-23T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/webpayments/keys/3", + "created": "2013-07-23T14:09:26Z", + "signatureValue": "mdMldVm9nIgSVpJVgLCKIDeXXf2A29K/0RHEIYx8lbHjJD/jdw877bJztwPiU48nZLtJ2yj03ehoyfiPANqG2vpxVug5cGmRNrvdrP0lKZtdMd/aeOxqShLb8YWwubcCeARuix9LY04+JemMlG2QM+MUY0a1QJFOMskL2gX7xDeaQJ16eACgTOTtG68KIGW82qyG8C5Iq7g3XD+CtUns2cCXD8+ECsOdWtkrCAyLwC/URiVdNBApAPbRfeOAcwzB5AadiqTXed2lkchaIF4he4+/yxdmJA0erceAlU4phl03qLvSj5TyQ0TIt54GLyzUwMFsSG5Cw1wCcKD/LeDJ9w==" + } + } + ] +} \ No newline at end of file diff --git a/routes/assets/140106c96be b/routes/assets/140106c96be new file mode 100644 index 0000000..e0d16b1 --- /dev/null +++ b/routes/assets/140106c96be @@ -0,0 +1,114 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/140106c96be", + "listingId": "140106c96be", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "51e96cc8a0e24c65b0000001" + }, + "title": "HTML5", + "assetContent": "https://webpayments.fwd.wf/assets/asset/140106c96be", + "assetProvider": "https://dev.payswarm.com/i/piatra", + "listingRestrictions": { + "validFrom": "2013-07-24T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/140106c96be/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-24T11:24:46Z", + "signatureValue": "LB6Sr6XnOWgAolWQ9O++kLDG92oOaJQMPxV4oLv6RwfAN1hPHvj/zGEUPI7aBLxA+gmiQ+9ZnFQuJXiKPOrauXvJNWf2mtT+AnySNdVP7jnuaBLaBompeC6iVocgpS9XRJPL8Pi586+1VTRHEnS/6YofCKyMbBZcvXCfWtQfLtWOG1yeB+Brdu/SwGLuyqreM6o6a8tk3gplmNWK3Su/4MIXeXu8ezdCvNgnBaIWfM9ntnsDJltCcz2p+6Cc1kRf3+9iR2gxYbR4vWBJkkhd0LBCbf9p3XE+6kVJhkFY6qTEp9a7eGriLdB2MG70LBfIk0TWhzCiIEg1be8x2sHzWg==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/140106c96be", + "assetId": "140106c96be", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/piatra", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/140106c96be/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "321 [140106c96be]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/140106c96be", + "assetHash": "urn:sha256:22c3716a5a2df24edc8bd05098707505e0b5ba6313fa6635eaa6af793ca3b58a", + "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-24T11:24:46Z", + "signatureValue": "LDFZwkHkBm4lqRn9PcmFatmnxLyl3WHgBuMhU44wyf0K2sZEzwOMkq3uq6wa2R7AnVcdzSnglI9pvncZtycIoUQKd8gX3nzKnaRua932prFB2DO5G3cUlHIbGaDq+KBvpblnzFX8bs1OFmZo//6DzWmKhOSJcb+y2NZ81vWT2YRAh1NdEMa/RjeaeRcFKLRKRuUJUWNcyXPtRx6Xd8L4Ev+rDy1YlXcb46+cCY5QMaCmIffY5yxdsYV8nP2OE/xqEZazN4hFRzb8Xz4Fn52k3iskUNc0M4yIlceqjPNIJp9JOWUDLYl1TMWlb8wa+03VJ+RYBjAb+/xiqVyxS26AQw==" + } + } + ] +} \ No newline at end of file diff --git a/routes/assets/140106cc3d7 b/routes/assets/140106cc3d7 new file mode 100644 index 0000000..a8695e9 --- /dev/null +++ b/routes/assets/140106cc3d7 @@ -0,0 +1,114 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/140106cc3d7", + "listingId": "140106cc3d7", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "51e96cc8a0e24c65b0000001" + }, + "title": "HTML5", + "assetContent": "https://webpayments.fwd.wf/assets/asset/140106cc3d7", + "assetProvider": "https://dev.payswarm.com/i/piatra", + "listingRestrictions": { + "validFrom": "2013-07-24T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/140106cc3d7/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-24T11:24:58Z", + "signatureValue": "YRkuho2qnggU9ZECIy9PPRo2EvMJOQh7aB7FT4Gbz2PGBGpPbFFM0ichUqECjOFbLZ+uHew/UsbJF6Vw+TvXo0Sm9mZzqwW1H3UOnD9jhwBscjsVE3dOlDeBSQHTPmHtnn8o5WsgklsNGa5PO8QsLNG44lWxrFOIPzGvYAQrSoAZKl3EAUiYApytXn0Moj+RTXhRzRPW+sVpFaXMRpEPbXklwUICYtZqzBn2wn4jCdhklef0SECzpSjmCOF2idjZb/W+K/xeX+BdviXijAjQLXfg7JI/95DW1E7agevEtyV+bid6MonBE9c1I98mJg6ZEdnzq9NlPTXmodCShYAqHg==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/140106cc3d7", + "assetId": "140106cc3d7", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/piatra", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/140106cc3d7/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "321 [140106cc3d7]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/140106cc3d7", + "assetHash": "urn:sha256:f555d1e176e5ac5393f944535596c6b0d458990063d2dddae0a5e5251c4f5bbd", + "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-24T11:24:58Z", + "signatureValue": "AGZ9ClbJOyfMz7wZrddrQQn6H4QyUVBBdkpfHhKncNEK/kAlN02oP/ZubzMM9qA9ksplA47ili7d9SqjPk2cRLiIxrz3Eur/FtL6zGrwSgbJLygVg/3ztQLETkVFtHUnIoZaHDR8u3ozwokYotM6wiY23wCd1SQD7pj0BYZBjJKCW6CSdnwlrafLkwtG0xz4IMbCdwDJ/1w3mkrkeKvlIO7TXACLMzkO2PtTBSuGBPElAhYd8MXe+I11Wx3+I0ni7YWqZdeCghV/i2mkw4EW781Raw/O8GtHEjDQBXu+UbHWoufuI7SAfSj+/IRucLat3HX2OjJgFLU/dkHDc99zQQ==" + } + } + ] +} \ No newline at end of file diff --git a/routes/assets/140106f1b0a b/routes/assets/140106f1b0a new file mode 100644 index 0000000..43a77d8 --- /dev/null +++ b/routes/assets/140106f1b0a @@ -0,0 +1,114 @@ +{ + "@context": "https://w3id.org/payswarm/v1", + "@graph": [ + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/assets/asset/140106f1b0a", + "listingId": "140106f1b0a", + "type": [ + "Asset", + "pto:WebPage" + ], + "creator": { + "fullName": "andrei.br92@gmail.com", + "userId": "51e96cc8a0e24c65b0000001" + }, + "title": "HTML5", + "assetContent": "https://webpayments.fwd.wf/assets/asset/140106f1b0a", + "assetProvider": "https://dev.payswarm.com/i/piatra", + "listingRestrictions": { + "validFrom": "2013-07-24T00:00:00Z", + "validUntil": "2013-07-31T00:00:00Z", + "payee": [ + { + "id": "https://webpayments.fwd.wf/assets/asset/140106f1b0a/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-24T11:27:31Z", + "signatureValue": "cSdCUMZRucxpgJv6C2rRTv7hd9K9MaoXILLBQiD0JWIVFSDTaaFdAO+ytq7fnt0+JqvreNiXhwLGAKuF57U2cEWBCmUgLqp6SkcoM8r0zDul9wOIoQLkeScebyhY3K7D8D7GsiXk07cc2yjNS1THUzufEPb/4lsbbYQ03Gc8G8lv+ZU2CiYgtJ5EYnjq2tHi2R7FW8JUv+NasKb7rD2Jk+ctjRrKL8E8cL1venBSNwJVS+G9qcjGu3yXNTstq/6LpF6HdgcnFp1eLmrGpyt9oyccz0DTTW9WXDkawD8KUR2MJaA4ZI8VVqLJxUo2wPBa1tuncUiNmdbYWw5aNR+NCA==" + } + }, + { + "@context": "https://w3id.org/payswarm/v1", + "id": "https://webpayments.fwd.wf/listings/listing/140106f1b0a", + "assetId": "140106f1b0a", + "type": [ + "Listing", + "gr:Offering" + ], + "vendor": "https://dev.payswarm.com/i/piatra", + "payee": [ + { + "id": "https://webpayments.fwd.wf/listings/listing/140106f1b0a/payee", + "type": "Payee", + "destination": "https://dev.payswarm.com/i/webpayments/accounts/incoming-payments", + "currency": "USD", + "payeeGroup": [ + "vendor" + ], + "payeeRate": "2", + "payeeRateType": "FlatAmount", + "payeeApplyType": "ApplyExclusively", + "comment": "123321 [140106f1b0a]." + } + ], + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "maximumPayeeRate": "10", + "payeeRateType": "Percentage", + "payeeApplyType": "ApplyInclusively" + } + ], + "asset": "https://webpayments.fwd.wf/assets/asset/140106f1b0a", + "assetHash": "urn:sha256:c1ced7e5a94049e259f8eaae3c0bdede9ce276bb72653971bad615ae05197828", + "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-24T11:27:31Z", + "signatureValue": "GlU1V0ArZMjM4vOnM5/7HB0C/umWS+D04mD5+qVY8AX8AsPKQouZudgNNmCVExH21xX1VY45nNfAfbK9Gxkx9t4biLh0rEoxG6uZgKCpbIUytg27ZOTEuGcLf96rJRuaXMjakwUTXC/0gFagNO4cPW9et8qtfBGVcBZ4/9F5hPOEH2ow2ttRdmI69N9VL8Y5X+0ZbBX04Ez/Yw4PcMoxh5tZpC3gXCp0ln5AN48YXEOe3Vzh9EkRzMq5ozuRfIRnjznRumbpSTWXKLYixLD4/GC0fUIfFyALlPIC8k3nITfyr08x29szYqYhqAR8OxKoW3Kb+RSyfcKY7XGe2jdAag==" + } + } + ] +} \ No newline at end of file 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 092ca08..cf4ffc5 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -36,7 +36,10 @@ var auth = { body = JSON.parse(body); if (body.status == 'okay') { user.checkUser(body, function (user) { - body.registered = user.registered; + + if (!user) body.registered = false; + else body.registered = user.registered; + keys.getKeyPair(function (err, keyPair) { if (err) { console.log(err); @@ -58,14 +61,36 @@ var auth = { }, + payswarmVerify: function (req, res) { + user.checkUser(req.body, function (user) { + res.json({ + registered: user.registered + }) + }) + }, + returnKeys: function (req, res, body, keyPair) { keyPair = JSON.parse(keyPair); body.publicKey = keyPair.publicKey.publicKeyPem; req.session.email = body.email; - res.json(body); + user.get({owner: 1, username: 1, registered:1}, {email: body.email}, function (err, doc) { + if (err) { + 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); + } + }) }, registerKey : function (req, res) { + console.log('req.body', req.body); async.waterfall([ function(callback) { payswarm.getWebKeysConfig('dev.payswarm.com', callback); @@ -74,7 +99,9 @@ var auth = { registrationUrl.query['public-key'] = req.body.publicKey; registrationUrl.query['response-nonce'] = new Date().getTime().toString(16); delete registrationUrl.search; + console.log('registrationUrl', registrationUrl); registrationUrl = URL.format(registrationUrl); + console.log('registrationUrl', registrationUrl); callback(null, registrationUrl) }, function(registrationUrl, callback) { @@ -92,6 +119,7 @@ var auth = { } catch (e) { console.log(e); } + console.log('got payswarm resp', paysw); keys.decode(paysw, function (err, message) { if (err) { showError(err, res); @@ -102,7 +130,9 @@ var auth = { destination : message.destination, registered : true } - user.updateFields(fields, {email : req.body.email}, function () { + user.updateFields(fields, {email : req.body.email}, function (err, docs) { + console.log(err, docs); + console.log('updated', {email : req.body.email}); status(err, res); }) } diff --git a/routes/index.js b/routes/index.js index 167a055..d837ca3 100644 --- a/routes/index.js +++ b/routes/index.js @@ -3,24 +3,39 @@ * Main pages */ -var title = 'WebPayments Marketplace' +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) { - res.render('index', { - title: title, - user : (req.session.email) ? req.session.email : false + assets.getUserAssets({}, function (assets) { + 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) { - res.render('newasset', { - title: title + ' - register asset', - user : (req.session.email) ? req.session.email : false - }); + res.render('newasset', options(req)); }; \ No newline at end of file diff --git a/routes/user.js b/routes/user.js new file mode 100644 index 0000000..a803101 --- /dev/null +++ b/routes/user.js @@ -0,0 +1,20 @@ +var user = require('../lib/user')(); + +module.exports = { + setUsername: function (req, res) { + console.log(user); + req.session.username = req.body.username; + user.updateFields({ + username: req.body.username + }, + { + email: req.body.email + }, function (err) { + if (err) { + console.log('error while updateing user',err); + } else { + res.end('Profile username updated!'); + } + }); + } +}; \ No newline at end of file diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..b9c43b4 --- /dev/null +++ b/test.txt @@ -0,0 +1,49 @@ +{ + "assetId": "51e5bbb32accfe6525000002", + "@context": "https://w3id.org/payswarm/v1", + "id": "http://listings.dev.payswarm.com/mozhacks/html5-me-song#listing", + "userId": "51cb00e7b544338396000001", + "vendor": "https://dev.payswarm.com/i/the-webdevs", + "asset": "http://listings.dev.payswarm.com/mozhacks/demo#asset", + "assetHash": "urn:sha256:04a349226b8aa3342d1f793572e3a3049c539144d1762547862f92b44c084af9", + "license": "https://w3id.org/payswarm/licenses/personal-use", + "licenseHash": "urn:sha256:73ebeac3656bf37419a02a9d5041226dcc42722d5256895d324519a7b6d7d690", + "validFrom": "2013-07-16T00:00:00.000Z", + "validUntil": "2013-07-21T00:00:00.000Z", + "signature": { + "type": "GraphSignature2012", + "creator": "https://dev.payswarm.com/i/authority/keys/1", + "created": "2013-07-16T21:31:29Z", + "signatureValue": "kv/uWVEhEbzig5LmBxAWqvShDM6GOiCL/8pXVG58N34VPmv6TPO8sHU1CEyg2PtL7UGdrRzJlj3gsWC7puyRPMt6SptU6VvFkXO8nP0unDFGUKOn1RfAzxgrMG9oxas/o/K+r6selfpKTygfYmdF+4aNDjh78bn3WwhJO4Wees+jH/5PDEY88dDdSw+c/ECkg4FPiMGQMzyG4TZwIu+AO2tNKSbicm44DJRbLYij+VeITbCJ/1R+LZlrJukKLqFTA/Km+3l7Tay100/xXvyCCzNCYf/LHwDCeBL7oiey9dx4YZYrtt/wQLUvNHI8jEIabjwCydz5I5DYKIOfwAVqXA==" + }, + "_id": "51e5bbb32accfe6525000001", + "__v": 0, + "payeeRule": [ + { + "type": "PayeeRule", + "payeeGroupPrefix": [ + "authority" + ], + "payeeRateType": "Percentage", + "maximumPayeeRate": "5", + "payeeApplyType": "ApplyInclusively" + } + ], + "payee": [ + { + "type": "Payee", + "destination": "https://dev.payswarm.com/i/the-webdevs/accounts/royalties", + "payeeGroup": [ + "vendor" + ], + "payeeRateType": "FlatAmount", + "payeeRate": "2", + "currency": "USD United States Dollars", + "payeeApplyType": "ApplyExclusively", + "comment": "this is a comment" + } + ], + "type": [ + "Listing" + ] +} \ 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 07f269b..16056a7 100644 --- a/views/index.jade +++ b/views/index.jade @@ -2,32 +2,28 @@ extends layout block content .container - h1 Welcome to the WebPayments Marketplace - p - | This application is implemented using - ul - li Mozilla Persona - li WebPayments - li PaySwarm - p You should sign up for an account and give it a try + .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 + hr .category - h4.category__title - | Newest - button.topcoat-button.pull-right See all + ul.tab-bar + li.topcoat-button Newest + li.topcoat-button Popular ul.item-container.container--newest - li - h4 Item name - p Item description - button.topcoat-button--cta Buy - li - h4 Item name - p Item description - button.topcoat-button--cta Buy - li - h4 Item name - p Item description - button.topcoat-button--cta Buy - li - h4 Item name - p Item description - button.topcoat-button--cta Buy \ No newline at end of file + - assets.forEach(function (asset, i) { + - url = '/assets/asset/' + asset.asset.listingId + '/purchase'; + li + h4= asset.asset.title + - 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 8fae9fc..a3e2ed3 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -7,21 +7,23 @@ html body .topcoat-navigation-bar .container - .topcoat-navigation-bar__item.left.quarter - a(class='topcoat-icon-button', href='/') Home - a(class='topcoat-icon-button', href='/newasset') Sell - a(class='topcoat-icon-button', href='/about') About + .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 WebPayments Marketplace - .topcoat-navigation-bar__item.right + h1.topcoat-navigation-bar__title= title || 'WebPayments Marketplace' + .topcoat-navigation-bar__item.right.quarter a.topcoat-icon-button--quiet - if (user) - a.right(class='topcoat-icon-button js-handler--login', href='#')= user + button.right(class='topcoat-icon-button', data-id=id) + .js-handler--email.inline= user .topcoat-notification .topcoat-list__container.list--medium ul.topcoat-list.js-handler--asset-list - else - a.right(class='js-handler--login', href='#'): img(src='/images/signin.png', title='Login') + a.right(class='js-handler--email js-handler--login', href='#'): img(src='/images/signin.png', title='Login') .messages block content script(src='https://login.persona.org/include.js') 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 2725d24..9860c98 100644 --- a/views/newasset.jade +++ b/views/newasset.jade @@ -2,51 +2,80 @@ extends layout block content .container - h1 Create a new asset - p make an asset and listing for a new good to sell - form.half.pull-left.js-handler--create-asset(action='/newasset/process/', method='POST') - table.table-form - tr - td: input(type='hidden', value=user, name='email') - tr - td: label Title - td: input(class='topcoat-text-input', type='text', name='title', placeholder='Asset title', value='HTML5', required) - tr - td: label Author - td: input(class='topcoat-text-input', type='text', name='author', placeholder='Asset creator', value='Joe', required) - tr - td: label Link to content - td: input(class='topcoat-text-input', type='file', name='assetContent',required) - tr - td: label Price - td - input.topcoat-text-input(type='number', step=0.01, name='payeeRate', value=2) - select.docNav(name='currency') - - tr - td Comments - td: textarea(class='topcoat-textarea', placeholder='Comments', name='comment') - tr - td: label Validity - td - - var today = new Date().toISOString().slice(0,10); - input(type='date', class='topcoat-text-input', name='validFrom', value=today, required) - input(type='date', class='topcoat-text-input', name='validUntil', required) - tr - td: label License - td - select.docNav(name='license') - option(selected='selected', value='https://w3id.org/payswarm/licenses/personal-use') Personal use - p - button(type='submit', class='topcoat-button--large--cta pull-right') Create asset - .half.pull-right - 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. - p Source - a(href='https://hacks.mozilla.org/2013/04/payswarm-part-2/') Web Payments with PaySwarm: Assets and Listings (part 2 of 3) + .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. + - else + h4 Complete the asset description + p: small: em You need to complete all of the fields below to create the asset and listing + - if (registered=='false') + h4 You are not registered yet + p: small: em You need to register with the payswarm authority + p.hidden(class='js-handler--show-payswarm-verify')= publicKey + .container + - if (!username) + form.half.pull-left.js-handler--change-username(action='/user/set/username', method='POST') + table.table-form + tr + td: label Username + td: input.topcoat-text-input(type='text', name='username', required) + tr + 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(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') + tr + td: label Title + td: input(class='topcoat-text-input', type='text', name='title', placeholder='Asset title', value='HTML5', required) + tr + td: label Author + td: input(class='topcoat-text-input', type='text', name='author', placeholder='Asset creator', value='Joe', required) + tr + td Description + td: textarea(class='topcoat-textarea full-width', placeholder='Comments', name='description') + tr + 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 + input.topcoat-text-input(type='number', step=0.01, name='price', value=2) + select.docNav(name='currency') + + tr + td Comments + td: textarea(class='topcoat-textarea', placeholder='Comments', name='comment') + tr + td: label Validity + td + - var today = new Date().toISOString().slice(0,10); + input(type='date', class='topcoat-text-input', name='validFrom', value=today, required) + input(type='date', class='topcoat-text-input', name='validUntil', required) + tr + td: label License + td + select.docNav(name='license') + option(selected='selected', value='https://w3id.org/payswarm/licenses/personal-use') Personal use + p + input(type='hidden', name='userId', value=id) + input(type='hidden', name='owner', value=identity) + 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. + p Source + a(href='https://hacks.mozilla.org/2013/04/payswarm-part-2/') Web Payments with PaySwarm: Assets and Listings (part 2 of 3) 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