define([ 'jquery', '/api/config', '/assert/assertions.js', '/common/hyperscript.js', '/customize/messages.js', '/common/dom-ready.js', '/bower_components/nthen/index.js', '/common/sframe-common-outer.js', '/customize/login.js', '/common/common-hash.js', '/common/common-util.js', '/common/pinpad.js', '/bower_components/tweetnacl/nacl-fast.min.js', 'less!/customize/src/less2/pages/page-checkup.less', ], function ($, ApiConfig, Assertions, h, Messages, DomReady, nThen, SFCommonO, Login, Hash, Util, Pinpad) { var assert = Assertions(); var trimSlashes = function (s) { if (typeof(s) !== 'string') { return s; } return s.replace(/\/+$/, ''); }; var _alert = function (content) { return h('span.advisory-text', content); }; var trimmedSafe = trimSlashes(ApiConfig.httpSafeOrigin); var trimmedUnsafe = trimSlashes(ApiConfig.httpUnsafeOrigin); assert(function (cb) { //console.error(trimmedSafe, trimmedUnsafe); cb(Boolean(trimmedSafe && trimmedUnsafe)); }, _alert("Sandbox configuration: ensure that both httpUnsafeOrigin and httpSafeOrigin are defined")); assert(function (cb) { return void cb(trimmedSafe !== trimmedUnsafe); }, _alert('Sandbox configuration: httpUnsafeOrigin !== httpSafeOrigin')); assert(function (cb) { cb((window.location.origin + '/') === ApiConfig.httpUnsafeOrigin); }, _alert('Sandbox configuration: loading via httpUnsafeOrigin')); var checkAvailability = function (url, cb) { $.ajax({ url: url, data: {}, complete: function (xhr) { cb(xhr.status === 200); }, }); }; assert(function (cb) { checkAvailability(trimmedUnsafe, cb); }, _alert("Main domain is not available")); // Try loading an iframe on the safe domain assert(function (cb) { var to; nThen(function (waitFor) { DomReady.onReady(waitFor()); }).nThen(function (waitFor) { to = setTimeout(function () { console.error('TIMEOUT loading iframe on the safe domain') cb(false); }, 5000); SFCommonO.initIframe(waitFor); }).nThen(function () { // Iframe is loaded clearTimeout(to); cb(true); }); }, _alert("Sandbox domain is not available")); // Write/ready access to /block/ assert(function (cb) { var bytes = new Uint8Array(Login.requiredBytes); var opt = Login.allocateBytes(bytes); var blockUrl = Login.Block.getBlockUrl(opt.blockKeys); var blockRequest = Login.Block.serialize("{}", opt.blockKeys); var removeRequest = Login.Block.remove(opt.blockKeys); console.log('Test block URL:', blockUrl); var userHash = '/2/drive/edit/000000000000000000000000'; var secret = Hash.getSecrets('drive', userHash); opt.keys = secret.keys; opt.channelHex = secret.channel; var RT, rpc, exists; nThen(function (waitFor) { Util.fetch(blockUrl, waitFor(function (err, block) { if (err) { return; } // No block found exists = true; })); }).nThen(function (waitFor) { // Create proxy Login.loadUserObject(opt, waitFor(function (err, rt) { if (err) { waitFor.abort(); console.error("Can't create new channel. This may also be a websocket issue."); return void cb(false); } RT = rt; var proxy = rt.proxy; proxy.edPublic = opt.edPublic; proxy.edPrivate = opt.edPrivate; proxy.curvePublic = opt.curvePublic; proxy.curvePrivate = opt.curvePrivate; rt.realtime.onSettle(waitFor()); })); }).nThen(function (waitFor) { // Init RPC Pinpad.create(RT.network, RT.proxy, waitFor(function (e, _rpc) { if (e) { waitFor.abort(); console.error("Can't initialize RPC", e); // INVALID_KEYS return void cb(false); } rpc = _rpc; })); }).nThen(function (waitFor) { // Write block if (exists) { return; } rpc.writeLoginBlock(blockRequest, waitFor(function (e) { if (e) { waitFor.abort(); console.error("Can't write login block", e); return void cb(false); } })); }).nThen(function (waitFor) { // Read block Util.fetch(blockUrl, waitFor(function (e, block) { if (e) { waitFor.abort(); console.error("Can't read login block", e); return void cb(false); } })); }).nThen(function (waitFor) { // Remove block rpc.removeLoginBlock(removeRequest, waitFor(function (e) { if (e) { waitFor.abort(); console.error("Can't remove login block", e); console.error(blockRequest); return void cb(false); } })); }).nThen(function (waitFor) { rpc.removeOwnedChannel(secret.channel, waitFor(function (e) { if (e) { waitFor.abort(); console.error("Can't remove channel", e); return void cb(false); } })); }).nThen(function () { cb(true); }); }, _alert("Login Block is not working (write/read/remove)")); var row = function (cells) { return h('tr', cells.map(function (cell) { return h('td', cell); })); }; var failureReport = function (obj) { return h('div.error', [ h('h5', obj.message), h('table', [ row(["Failed test number", obj.test + 1]), row(["Returned value", obj.output]), ]), ]); }; assert.run(function (state) { var errors = state.errors; var failed = errors.length; Messages.assert_numberOfTestsPassed = "{0} / {1} tests passed."; var statusClass = failed? 'failure': 'success'; var summary = h('div.summary.' + statusClass, [ h('p', Messages._getKey('assert_numberOfTestsPassed', [ state.passed, state.total ])), h('p', "Details found below"), ]); var report = h('div.report', [ summary, h('div.failures', errors.map(failureReport)), ]); $('body').prepend(report); }); });