From e970c46b8cc6e425c250494f301bb35f97f82d9b Mon Sep 17 00:00:00 2001 From: ArnaudCerisier <arnaud.cerisier@gmail.com> Date: Mon, 21 Aug 2017 23:59:46 +0200 Subject: [PATCH] [enh] display license as HTML - fix #538 [fix] Fallback to default license locale - fix #539 [enh] Build web release: preparing API files --- .gitignore | 5 +- app/config.json | 8 +- gulpfile.js | 119 ++++++++- ionic.project | 1 + package.json | 277 +++++++++++---------- www/api/index.html | 7 +- www/js/config.js | 6 +- www/js/controllers/currency-controllers.js | 7 +- www/js/controllers/join-controllers.js | 4 + www/js/services/settings-services.js | 2 +- www/license/license_g1-en.md | 79 ++++++ www/license/license_g1-fr-FR.md | 75 ++++++ www/templates/currency/modal_license.html | 2 +- 13 files changed, 431 insertions(+), 161 deletions(-) create mode 100644 www/license/license_g1-en.md create mode 100644 www/license/license_g1-fr-FR.md diff --git a/.gitignore b/.gitignore index f3180c670..d350a74f0 100644 --- a/.gitignore +++ b/.gitignore @@ -21,10 +21,13 @@ /www/js/config.js # Generated CSS - /www/css/ionic.app.css /www/css/ionic.app.min.css +# Generated License files +/www/license/*.html +/www/license/*.txt + # Leaflet generated files /www/css/leaflet.app.css /www/css/leaflet.app.min.css diff --git a/app/config.json b/app/config.json index 51ea57242..37f70f93b 100644 --- a/app/config.json +++ b/app/config.json @@ -19,8 +19,8 @@ "installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md" }, "license": { - "fr-FR": "license/license_g1-fr-FR.txt", - "en": "license/license_g1-en.txt" + "fr-FR": "license/license_g1-fr-FR", + "en": "license/license_g1-en" }, "node": { "host": "g1.duniter.org", @@ -76,8 +76,8 @@ "installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md" }, "license": { - "fr-FR": "license/license_g1-fr-FR.txt", - "en": "license/license_g1-en.txt" + "fr-FR": "license/license_g1-fr-FR", + "en": "license/license_g1-en" }, "node": { "host": "g1.duniter.fr", diff --git a/gulpfile.js b/gulpfile.js index d82fcb61f..9a606a499 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -14,6 +14,7 @@ var ngConstant = require('gulp-ng-constant'); var fs = require("fs"); var argv = require('yargs').argv; var header = require('gulp-header'); +var footer = require('gulp-footer'); var removeCode = require('gulp-remove-code'); var removeHtml = require('gulp-html-remove'); var templateCache = require('gulp-angular-templatecache'); @@ -34,6 +35,7 @@ var htmlmin = require('gulp-htmlmin'); var jshint = require('gulp-jshint'); var sourcemaps = require('gulp-sourcemaps'); var concatCss = require('gulp-concat-css'); +var markdown = require('gulp-markdown'); var paths = { sass: ['./scss/**/*.scss'], @@ -45,11 +47,12 @@ var paths = { templatecache_plugin: ['./www/plugins/*/templates/**/*.html'], ng_translate_plugin: ['./www/plugins/*/i18n/locale-*.json'], ng_annotate_plugin: ['./www/plugins/*/**/*.js', '!./www/plugins/*/js/vendor/*.js'], - css_plugin: ['./www/plugins/*/css/**/*.css'] + css_plugin: ['./www/plugins/*/css/**/*.css'], + license_md: ['./www/license/*.md'] }; gulp.task('default', ['sass', 'config', 'templatecache', 'ng_translate', 'ng_annotate', - 'templatecache_plugin', 'ng_translate_plugin', 'ng_annotate_plugin', 'css_plugin' + 'templatecache_plugin', 'ng_translate_plugin', 'ng_annotate_plugin', 'css_plugin', 'license_md' ]); gulp.task('sass-images', function (done) { @@ -113,6 +116,7 @@ gulp.task('watch', function() { gulp.watch(paths.ng_annotate_plugin, ['ng_annotate_plugin']); gulp.watch(paths.ng_translate_plugin, ['ng_translate_plugin']); gulp.watch(paths.css_plugin, ['css_plugin']); + gulp.watch(paths.license_md, ['license_md']); }); gulp.task('install', ['git-check'], function() { @@ -195,6 +199,25 @@ gulp.task('ng_translate', function() { }); +gulp.task('license_md', function (done) { + es.concat( + // Copy license into HTML + gulp.src(paths.license_md) + .pipe(markdown()) + .pipe(header('<html><header><meta charset="utf-8"></header><body>')) + .pipe(footer('</body></html>')) + .pipe(gulp.dest('www/license')), + + // Copy license into txt + gulp.src(paths.license_md) + .pipe(header('\ufeff')) // Need BOM character for UTF-8 files + .pipe(rename({ extname: '.txt' })) + .pipe(gulp.dest('www/license')) + ) + .on('end', done); +}); + + gulp.task('debug_file', function() { gutil.log(gutil.colors.green("Building `www/debug.html`...")); @@ -276,7 +299,7 @@ gulp.task('copy-files:web', ['clean:tmp', 'clean:web', 'sass', 'config'], functi // Copy index.html (and remove unused code) gulp.src('./www/index.html') - .pipe(removeCode({"no-device": true})) + .pipe(removeCode({'no-device': true})) .pipe(removeHtml('.hidden-no-device')) .pipe(removeHtml('[remove-if][remove-if="no-device"]')) .pipe(htmlmin()) @@ -284,12 +307,28 @@ gulp.task('copy-files:web', ['clean:tmp', 'clean:web', 'sass', 'config'], functi // Copy index.html to debug.html (and remove unused code) gulp.src('./www/index.html') - .pipe(removeCode({"no-device": true})) + .pipe(removeCode({'no-device': true})) .pipe(removeHtml('.hidden-no-device')) .pipe(removeHtml('[remove-if][remove-if="no-device"]')) .pipe(rename("debug.html")) .pipe(gulp.dest(tmpPath)), + // Copy API index.html + gulp.src('./www/api/index.html') + .pipe(removeCode({'no-device': true})) + .pipe(removeHtml('.hidden-no-device')) + .pipe(removeHtml('[remove-if][remove-if="no-device"]')) + .pipe(htmlmin()) + .pipe(gulp.dest(tmpPath + '/api')), + + // Copy API index.html + gulp.src('./www/api/index.html') + .pipe(removeCode({'no-device': true})) + .pipe(removeHtml('.hidden-no-device')) + .pipe(removeHtml('[remove-if][remove-if="no-device"]')) + .pipe(rename("debug.html")) + .pipe(gulp.dest(tmpPath + '/api')), + // Copy fonts gulp.src('./www/fonts/**/*.*') .pipe(gulp.dest(tmpPath + '/fonts')), @@ -315,9 +354,17 @@ gulp.task('copy-files:web', ['clean:tmp', 'clean:web', 'sass', 'config'], functi gulp.src('./www/lib/ionic/**/*.*') .pipe(gulp.dest(tmpPath + '/lib/ionic')), - // Copy license - gulp.src('./www/license/**/*.txt') + // Copy license into HTML + gulp.src('./www/license/*.md') + .pipe(markdown()) + .pipe(header('<html><header><meta charset="utf-8"></header><body>')) + .pipe(footer('</body></html>')) + .pipe(gulp.dest(tmpPath + '/license')), + + // Copy license into txt + gulp.src('./www/license/*.md') .pipe(header('\ufeff')) // Need BOM character for UTF-8 files + .pipe(rename({ extname: '.txt' })) .pipe(gulp.dest(tmpPath + '/license')) ) @@ -382,11 +429,65 @@ gulp.task('ng_annotate-plugin:web', ['templatecache-plugin:web'], function (done .on('end', done); }); +gulp.task('debug-api-files:web', ['ng_annotate:web', 'ng_annotate-plugin:web'], function(done) { + var tmpPath = './platforms/web/www'; + var debugFilter = filter('**/debug.html', { restore: true }); + + gulp.src(tmpPath + '/*/debug.html') + .pipe(useref()) // Concatenate with gulp-useref + + .pipe(debugFilter) + .pipe(replace("dist_js", "../dist_js")) + .pipe(replace("dist_css", "../dist_css")) + .pipe(replace("config.js", "../config.js")) + .pipe(debugFilter.restore) -gulp.task('debug-files:web', ['ng_annotate:web', 'ng_annotate-plugin:web'], function(done) { + .pipe(gulp.dest(tmpPath)) + .on('end', done); +}); + +gulp.task('optimize-api-files:web', ['debug-api-files:web'], function(done) { var tmpPath = './platforms/web/www'; + var jsFilter = filter(["**/*.js", '!**/config.js'], { restore: true }); + var cssFilter = filter("**/*.css", { restore: true }); + var revFilesFilter = filter(['**/*', '!**/index.html', '!**/config.js'], { restore: true }); + var indexFilter = filter('**/index.html', { restore: true }); - gulp.src(tmpPath + '/debug.html') + // Process index.html + gulp.src(tmpPath + '/*/index.html') + .pipe(useref()) // Concatenate with gulp-useref + + // Process JS + .pipe(jsFilter) + .pipe(uglify()) // Minify any javascript sources + .pipe(jsFilter.restore) + + // Process CSS + .pipe(cssFilter) + .pipe(csso()) // Minify any CSS sources + .pipe(cssFilter.restore) + + // Add revision to filename (but not index.html and config.js) + .pipe(revFilesFilter) + .pipe(rev()) // Rename the concatenated files + .pipe(revFilesFilter.restore) + + .pipe(revReplace()) // Substitute in new filenames + + .pipe(indexFilter) + .pipe(replace("dist_js", "../dist_js")) + .pipe(replace("dist_css", "../dist_css")) + .pipe(replace("config.js", "../config.js")) + .pipe(indexFilter.restore) + + .pipe(gulp.dest(tmpPath)) + .on('end', done); + +}); + +gulp.task('debug-files:web', ['optimize-api-files:web'], function(done) { + var tmpPath = './platforms/web/www'; + gulp.src(tmpPath + '/*/debug.html') .pipe(useref()) // Concatenate with gulp-useref .pipe(gulp.dest(tmpPath)) .on('end', done); @@ -401,6 +502,7 @@ gulp.task('optimize-files:web', ['debug-files:web'], function(done) { // Process index.html gulp.src(tmpPath + '/index.html') .pipe(useref()) // Concatenate with gulp-useref + // Process JS .pipe(jsFilter) .pipe(uglify()) // Minify any javascript sources @@ -419,6 +521,7 @@ gulp.task('optimize-files:web', ['debug-files:web'], function(done) { .pipe(revReplace()) // Substitute in new filenames .pipe(gulp.dest(tmpPath)) .on('end', done); + }); gulp.task('clean-unused-files:web', ['optimize-files:web'], function(done) { diff --git a/ionic.project b/ionic.project index e7acc6600..fa97d5314 100644 --- a/ionic.project +++ b/ionic.project @@ -16,6 +16,7 @@ "ng_annotate_plugin", "ng_translate_plugin", "css_plugin", + "license_md", "watch" ], "defaultBrowser": "chrome", diff --git a/package.json b/package.json index 53de2654d..09851551f 100644 --- a/package.json +++ b/package.json @@ -1,142 +1,143 @@ { - "name": "cesium", - "version": "0.16.1", - "description": "Unhosted webapp client for Duniter network", - "repository": { - "type": "git", - "url": "git@github.com:duniter/cesium.git" + "name": "cesium", + "version": "0.16.1", + "description": "Unhosted webapp client for Duniter network", + "repository": { + "type": "git", + "url": "git@github.com:duniter/cesium.git" + }, + "scripts": { + "postinstall": "bower install", + "install-platforms": "ionic state restore", + "start": "ionic serve" + }, + "keywords": [ + "duniter", + "cesium", + "ionic", + "angular", + "cordova", + "crypto-currency" + ], + "author": "Duniter team", + "license": "GPL-3.0", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/duniter/cesium/issues", + "new": "https://github.com/duniter/cesium/issues/new?labels=bug" + }, + "dependencies": { + "bower": "^1.8.0", + "cordova-android": "^6.2.3", + "cordova-plugin-camera": "^2.4.1", + "cordova-plugin-compat": "^1.1.0", + "cordova-plugin-console": "^1.0.7", + "cordova-plugin-crosswalk-webview": "^2.3.0", + "cordova-plugin-device": "^1.1.6", + "cordova-plugin-dialogs": "^1.3.3", + "cordova-plugin-inappbrowser": "^1.7.1", + "cordova-plugin-minisodium": "^1.0.0", + "cordova-plugin-secure-storage": "^2.6.8", + "cordova-plugin-splashscreen": "^3.2.2", + "cordova-plugin-statusbar": "^2.2.3", + "cordova-plugin-vibration": "^2.1.5", + "cordova-plugin-websocket": "^0.12.2", + "cordova-plugin-whitelist": "^1.3.2", + "cordova-plugin-x-toast": "^2.6.0", + "delete-empty": "^0.1.3", + "gulp": "^3.9.1", + "gulp-bump": "^2.1.0", + "gulp-concat": "^2.2.0", + "gulp-rename": "^1.2.0", + "gulp-sass": "^2.2.0", + "ionic": "^1.7.16", + "ionic-plugin-keyboard": "^2.2.1", + "node-sass": "^3.3.3", + "phonegap-plugin-barcodescanner": "git+https://github.com/phonegap/phonegap-plugin-barcodescanner.git" + }, + "devDependencies": { + "cordova-uglify": "^0.2.3", + "del": "^2.2.0", + "fs": "0.0.2", + "gulp": "^3.9.1", + "gulp-angular-templatecache": "^1.8.0", + "gulp-angular-translate": "^0.1.4", + "gulp-base64": "^0.1.3", + "gulp-clean": "^0.3.2", + "gulp-clean-css": "^2.0.10", + "gulp-concat-css": "^2.3.0", + "gulp-css-base64": "^1.3.4", + "gulp-csso": "^2.0.0", + "gulp-filter": "^4.0.0", + "gulp-header": "^1.7.1", + "gulp-html-remove": "^0.1.1", + "gulp-htmlmin": "^2.0.0", + "gulp-jshint": "^2.0.1", + "gulp-markdown": "^1.2.0", + "gulp-ng-annotate": "^2.0.0", + "gulp-ng-constant": "^1.1.0", + "gulp-remove-code": "^1.0.2", + "gulp-replace": "^0.5.4", + "gulp-rev": "^7.0.0", + "gulp-rev-replace": "^0.4.3", + "gulp-sourcemaps": "^1.6.0", + "gulp-uglify": "^1.5.3", + "gulp-useref": "^3.1.0", + "gulp-util": "^2.2.14", + "gulp-zip": "^3.2.0", + "ionic-minify": "^2.0.8", + "jshint": "^2.9.2", + "mv": "^2.1.1", + "playup": "^1.0.2", + "shelljs": "^0.3.0", + "yargs": "^4.3.1" + }, + "cordovaPlugins": [ + "cordova-plugin-whitelist", + "cordova-plugin-splashscreen", + "cordova-plugin-console", + "ionic-plugin-keyboard", + "cordova-plugin-device", + "cordova-plugin-statusbar", + "cordova-plugin-camera", + "cordova-plugin-websocket", + "cordova-plugin-vibration", + "cordova-plugin-dialogs", + "cordova-plugin-minisodium", + "cordova-plugin-secure-storage", + { + "locator": "https://github.com/phonegap/phonegap-plugin-barcodescanner.git", + "id": "phonegap-plugin-barcodescanner" }, - "scripts": { - "postinstall": "bower install", - "install-platforms": "ionic state restore", - "start": "ionic serve" + "cordova-plugin-inappbrowser", + "cordova-plugin-x-toast" + ], + "cordovaPlatforms": [ + "android", + "firefoxos" + ], + "cordova": { + "plugins": { + "cordova-plugin-camera": {}, + "cordova-plugin-console": {}, + "cordova-plugin-device": {}, + "cordova-plugin-dialogs": {}, + "cordova-plugin-inappbrowser": {}, + "cordova-plugin-minisodium": {}, + "cordova-plugin-secure-storage": {}, + "cordova-plugin-splashscreen": {}, + "cordova-plugin-statusbar": {}, + "cordova-plugin-vibration": {}, + "cordova-plugin-websocket": {}, + "cordova-plugin-whitelist": {}, + "cordova-plugin-x-toast": {}, + "ionic-plugin-keyboard": {}, + "phonegap-plugin-barcodescanner": { + "CAMERA_USAGE_DESCRIPTION": " " + } }, - "keywords": [ - "duniter", - "cesium", - "ionic", - "angular", - "cordova", - "crypto-currency" - ], - "author": "Duniter team", - "license": "GPL-3.0", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/duniter/cesium/issues", - "new": "https://github.com/duniter/cesium/issues/new?labels=bug" - }, - "dependencies": { - "bower": "^1.8.0", - "cordova-android": "^6.2.3", - "cordova-plugin-camera": "^2.4.1", - "cordova-plugin-compat": "^1.1.0", - "cordova-plugin-console": "^1.0.7", - "cordova-plugin-crosswalk-webview": "^2.3.0", - "cordova-plugin-device": "^1.1.6", - "cordova-plugin-dialogs": "^1.3.3", - "cordova-plugin-inappbrowser": "^1.7.1", - "cordova-plugin-minisodium": "^1.0.0", - "cordova-plugin-secure-storage": "^2.6.8", - "cordova-plugin-splashscreen": "^3.2.2", - "cordova-plugin-statusbar": "^2.2.3", - "cordova-plugin-vibration": "^2.1.5", - "cordova-plugin-websocket": "^0.12.2", - "cordova-plugin-whitelist": "^1.3.2", - "cordova-plugin-x-toast": "^2.6.0", - "delete-empty": "^0.1.3", - "gulp": "^3.9.1", - "gulp-bump": "^2.1.0", - "gulp-concat": "^2.2.0", - "gulp-rename": "^1.2.0", - "gulp-sass": "^2.2.0", - "ionic": "^1.7.16", - "ionic-plugin-keyboard": "^2.2.1", - "node-sass": "^3.3.3", - "phonegap-plugin-barcodescanner": "git+https://github.com/phonegap/phonegap-plugin-barcodescanner.git" - }, - "devDependencies": { - "cordova-uglify": "^0.2.3", - "del": "^2.2.0", - "fs": "0.0.2", - "gulp": "^3.9.1", - "gulp-angular-templatecache": "^1.8.0", - "gulp-angular-translate": "^0.1.4", - "gulp-base64": "^0.1.3", - "gulp-clean": "^0.3.2", - "gulp-clean-css": "^2.0.10", - "gulp-concat-css": "^2.3.0", - "gulp-css-base64": "^1.3.4", - "gulp-csso": "^2.0.0", - "gulp-filter": "^4.0.0", - "gulp-header": "^1.7.1", - "gulp-html-remove": "^0.1.1", - "gulp-htmlmin": "^2.0.0", - "gulp-jshint": "^2.0.1", - "gulp-ng-annotate": "^2.0.0", - "gulp-ng-constant": "^1.1.0", - "gulp-remove-code": "^1.0.2", - "gulp-replace": "^0.5.4", - "gulp-rev": "^7.0.0", - "gulp-rev-replace": "^0.4.3", - "gulp-sourcemaps": "^1.6.0", - "gulp-uglify": "^1.5.3", - "gulp-useref": "^3.1.0", - "gulp-util": "^2.2.14", - "gulp-zip": "^3.2.0", - "ionic-minify": "^2.0.8", - "jshint": "^2.9.2", - "mv": "^2.1.1", - "playup": "^1.0.2", - "shelljs": "^0.3.0", - "yargs": "^4.3.1" - }, - "cordovaPlugins": [ - "cordova-plugin-whitelist", - "cordova-plugin-splashscreen", - "cordova-plugin-console", - "ionic-plugin-keyboard", - "cordova-plugin-device", - "cordova-plugin-statusbar", - "cordova-plugin-camera", - "cordova-plugin-websocket", - "cordova-plugin-vibration", - "cordova-plugin-dialogs", - "cordova-plugin-minisodium", - "cordova-plugin-secure-storage", - { - "locator": "https://github.com/phonegap/phonegap-plugin-barcodescanner.git", - "id": "phonegap-plugin-barcodescanner" - }, - "cordova-plugin-inappbrowser", - "cordova-plugin-x-toast" - ], - "cordovaPlatforms": [ - "android", - "firefoxos" - ], - "cordova": { - "plugins": { - "cordova-plugin-camera": {}, - "cordova-plugin-console": {}, - "cordova-plugin-device": {}, - "cordova-plugin-dialogs": {}, - "cordova-plugin-inappbrowser": {}, - "cordova-plugin-minisodium": {}, - "cordova-plugin-secure-storage": {}, - "cordova-plugin-splashscreen": {}, - "cordova-plugin-statusbar": {}, - "cordova-plugin-vibration": {}, - "cordova-plugin-websocket": {}, - "cordova-plugin-whitelist": {}, - "cordova-plugin-x-toast": {}, - "ionic-plugin-keyboard": {}, - "phonegap-plugin-barcodescanner": { - "CAMERA_USAGE_DESCRIPTION": " " - } - }, - "platforms": [ - "android" - ] - } + "platforms": [ + "android" + ] + } } diff --git a/www/api/index.html b/www/api/index.html index 0b0f2f626..2940e3421 100644 --- a/www/api/index.html +++ b/www/api/index.html @@ -7,10 +7,9 @@ <title>Cesium API</title> <link rel="icon" href="../img/favicon.ico"> - <!-- build:css dist_css/cesium.css --> + <!-- build:css dist_css/cesium-api.css --> <link rel="stylesheet" type="text/css" href="../css/ionic.app.min.css"> <link rel="stylesheet" type="text/css" href="../css/style.css"> - <link rel="stylesheet" type="text/css" href="../css/angular-image-crop.css"> <!--removeIf(device)--> <link rel="stylesheet" type="text/css" href="../css/style-no-device.css"> <!--endRemoveIf(device)--> @@ -24,7 +23,7 @@ <h4 style="text-align: center;">Loading...</h4> </ion-nav-view> -<!-- build:js dist_js/vendor.js --> +<!-- build:js dist_js/vendor-api.js --> <!-- vendor js --> <script src="../js/vendor/moment.min.js"></script> <script src="../js/vendor/moment.fr.js"></script> @@ -70,7 +69,7 @@ <script src="../cordova.js"></script> <!--endRemoveIf(no-device)--> -<!-- build:js dist_js/cesium.js --> +<!-- build:js dist_js/cesium-api.js --> <!-- services --> <script src="../dist/dist_js/app/services/settings-services.js"></script> <script src="../dist/dist_js/app/services/network-services.js"></script> diff --git a/www/js/config.js b/www/js/config.js index 19d1a4f9d..60dfb25af 100644 --- a/www/js/config.js +++ b/www/js/config.js @@ -28,8 +28,8 @@ angular.module("cesium.config", []) "installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md" }, "license": { - "fr-FR": "license/license_g1-fr-FR.txt", - "en": "license/license_g1-en.txt" + "fr-FR": "license/license_g1-fr-FR", + "en": "license/license_g1-en" }, "node": { "host": "g1.duniter.org", @@ -67,7 +67,7 @@ angular.module("cesium.config", []) } }, "version": "0.16.1", - "build": "2017-08-21T16:34:01.720Z", + "build": "2017-08-21T21:55:39.967Z", "newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug" }) diff --git a/www/js/controllers/currency-controllers.js b/www/js/controllers/currency-controllers.js index 9a1b537e7..ac2a27c7b 100644 --- a/www/js/controllers/currency-controllers.js +++ b/www/js/controllers/currency-controllers.js @@ -355,6 +355,11 @@ function CurrencyLicenseModalController($scope, $http, UIUtils, csSettings, File $scope.load = function() { if ($scope.loading) { $scope.licenseUrl = csSettings.getLicenseUrl(); + // Use HTML in iframe, when original file is markdown (fix #538) + if ($scope.licenseUrl && $scope.licenseUrl.substring($scope.licenseUrl.length - 3) != '.txt') { + $scope.licenseUrlHtml = $scope.licenseUrl + '.html'; + $scope.licenseUrl = $scope.licenseUrl +'.txt'; + } $scope.loading = false; } }; @@ -366,7 +371,7 @@ function CurrencyLicenseModalController($scope, $http, UIUtils, csSettings, File .success(function(data){ var file = new Blob([data], {type: 'text/plain; charset=utf-8'}); FileSaver.saveAs(file, 'license.txt'); - }).error(function(data){ + }).error(function(){ UIUtils.onError('ERROR.GET_LICENSE_FILE_FAILED')(); }); diff --git a/www/js/controllers/join-controllers.js b/www/js/controllers/join-controllers.js index 64c529096..cd7a6b1bd 100644 --- a/www/js/controllers/join-controllers.js +++ b/www/js/controllers/join-controllers.js @@ -140,6 +140,10 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt if ($scope.accountType == 'member') { $scope.licenseFileUrl = csSettings.getLicenseUrl(); if ($scope.licenseFileUrl) { + // Use HTML in iframe, when original file is markdown (fix #538) + if ( $scope.licenseFileUrl.substring($scope.licenseFileUrl.length - 3) != '.txt') { + $scope.licenseFileUrl = $scope.licenseFileUrl + '.html'; + } $scope.startListenLicenseBottom(); } } diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js index e43bce9dd..604609225 100644 --- a/www/js/services/settings-services.js +++ b/www/js/services/settings-services.js @@ -225,7 +225,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) getLicenseUrl = function() { var locale = data.locale && data.locale.id || csConfig.defaultLanguage || 'en'; return (csConfig.license) ? - (csConfig.license[locale] ? csConfig.license[locale] : csConfig.license) : undefined; + (csConfig.license[locale] ? csConfig.license[locale] : csConfig.license[csConfig.defaultLanguage || 'en'] || csConfig.license) : undefined; }, // Detect locale sucessuf changes, then apply to vendor libs diff --git a/www/license/license_g1-en.md b/www/license/license_g1-en.md new file mode 100644 index 000000000..ccb2586f2 --- /dev/null +++ b/www/license/license_g1-en.md @@ -0,0 +1,79 @@ + +License Ğ1 - v0.2.3 +=================== + +:date: 2017-08-21 16:59 +:modified: 2017-08-21 16:59 + +**Money licensing and liability commitment.** + +Any certification operation of a new member of Ğ1 must first be accompanied by the transmission of this license of the currency Ğ1 whose certifier must ensure that it has been studied, understood and accepted by the person who will be certified. + +Money Ğ1 +-------- + +Ğ1 occurs via a Universal Dividend (DU) for any human member, which is of the form: + +* 1 DU per person per day + +The amount of DU is identical each day until the next equinox, where the DU will then be reevaluated according to the formula: + +* DU <sub>day</sub> (the following equinox) = DU <day>(equinox) + c² (M / N) (equinox) / (15778800 seconds)</day> + +With as parameters: + +* c = 4.88% / equinox +* UD (0) = 10.00 Ğ1 + +And as variables: + +* _M_ the total monetary mass at the equinox +* _N_ the number of members at the equinox + +Web of Trust Ğ1 (WoT Ğ1) +------------------------ + +**Warning:** Certifying is not just about making sure you've met the person, it's ensuring that the community Ğ1 knows the certified person well enough and Duplicate account made by a person certified by you, or other types of problems (disappearance ...), by cross-checking that will reveal the problem if necessary. + +When you are a member of Ğ1 and you are about to certify a new account: + +**You are assured:** + +1°) The person who declares to manage this public key (new account) and to have personally checked with him that this is the public key is sufficiently well known (not only to know this person visually) that you are about to certify. + +2a°) To meet her physically to make sure that it is this person you know who manages this public key. + +2b°) Remotely verify the public person / key link by contacting the person via several different means of communication, such as social network + forum + mail + video conference + phone (acknowledge voice). + +Because if you can hack an email account or a forum account, it will be much harder to imagine hacking four distinct means of communication, and mimic the appearance (video) as well as the voice of the person . + +However, the 2 °) is preferable to 3 °, whereas the 1 °) is always indispensable in all cases. + +3 °) To have verified with the person concerned that he has indeed generated his Duniter account revocation document, which will enable him, if necessary, to cancel his account (in case of account theft, ID, an incorrectly created account, etc.). + +**Abbreviated WoT rules:** + +Each member has a stock of 100 possible certifications, which can only be issued at the rate of 1 certification / 5 days. + +Valid for 2 months, certification for a new member is definitively adopted only if the certified has at least 4 other certifications after these 2 months, otherwise the entry process will have to be relaunched. + +To become a new member of WoT Ğ1 therefore 5 certifications must be obtained at a distance> 5 of 80% of the WoT sentinels. + +A member of the TdC Ğ1 is sentinel when he has received and issued at least Y [N] certifications where N is the number of members of the TdC and Y [N] = ceiling N ^ (1/5). Examples: + +* For 1024 < N ≤ 3125 we have Y [N] = 5 +* For 7776 < N ≤ 16807 we have Y [N] = 7 +* For 59049 < N ≤ 100 000 we have Y [N] = 10 + +Once the new member is part of the WoT Ğ1 his certifications remain valid for 2 years. + +To remain a member, you must renew your agreement regularly with your private key (every 12 months) and make sure you have at least 5 certifications valid after 2 years. + +Software Ğ1 and license Ğ1 +-------------------------- + +The software Ğ1 allowing users to manage their use of Ğ1 must transmit this license with the software and all the technical parameters of the currency Ğ1 and TdC Ğ1 which are entered in block 0 of Ğ1. + +For more details in the technical details it is possible to consult directly the code of Duniter which is a free software and also the data of the blockchain Ğ1 by retrieving it via a Duniter instance or node Ğ1. + +More information on the Duniter Team website [https://www.duniter.org](https://www.duniter.org) diff --git a/www/license/license_g1-fr-FR.md b/www/license/license_g1-fr-FR.md new file mode 100644 index 000000000..5e6c3562a --- /dev/null +++ b/www/license/license_g1-fr-FR.md @@ -0,0 +1,75 @@ + +Licence Ğ1 - v0.2.3 +=================== + +:date: 2017-08-21 16:59 +:modified: 2017-08-21 16:59 + +**Licence de la monnaie et engagement de responsabilité.** + +Toute opération de certification d'un nouveau membre de Ğ1 doit préalablement s'accompagner de la transmission de cette licence de la monnaie Ğ1 dont le certificateur doit s'assurer qu'elle a été étudiée, comprise et acceptée par la personne qui sera certifiée. + +Monnaie Ğ1 +---------- + +Ğ1 se produit via un Dividende Universel (DU) pour tout être humain membre de la Toile de Confiance Ğ1, qui est de la forme : + +* 1 DU par personne et par jour + +Le montant du DU est identique chaque jour jusqu'au prochain équinoxe, où le DU sera alors réévalué selon la formule (avec 1 jour = 86 400 secondes) : + +* DUjour(équinoxe suivant) = DUjour(équinoxe) + c² (M/N)(équinoxe) / (182,625 jours) + +Avec comme paramètres : + +* c = 4,88% / équinoxe +* UD(0) = 10,00 Ğ1 + +Et comme variables : + +* *M* la masse monétaire totale à l'équinoxe +* *N* le nombre de membres à l'équinoxe + +Toile de confiance Ğ1 (TdC Ğ1) +------------------------------ + +**Avertissement :** Certifier n'est pas uniquement s'assurer que vous avez rencontré la personne, c'est assurer à la communauté Ğ1 que vous connaissez suffisamment bien la personne certifiée et que vous saurez ainsi la contacter facilement, et être en mesure de repérer un double compte effectué par une personne certifiée par vous-même, ou d'autres types de problèmes (disparition...), en effectuant des recoupements qui permettront de révéler le problème le cas échéant. + +Lorsque vous êtes membre de la TdC Ğ1 et que vous vous apprêtez à certifier un nouveau compte : + +**Vous êtes vous assuré :** + +1°) De suffisamment bien connaître (pas seulement de la connaître "de visu") la personne qui déclare gérer cette clé publique (nouveau compte) et d'avoir personnellement vérifié avec elle qu'il s'agit bien de cette clé publique que vous vous apprêtez à certifier. + +2a°) De la rencontrer physiquement pour vous assurer que c'est bien cette personne que vous connaissez qui gère cette clé publique. + +2b°) Ou bien de vérifer à distance le lien personne / clé publique en contactant la personne par plusieurs moyens de communication différents, comme réseau social + forum + mail + vidéo conférence + téléphone (reconnaître la voix). Car si l'on peut pirater un compte mail ou un compte forum, il sera bien plus difficile d'imaginer pirater quatre moyens de communication distincts, et imiter l'apparence (vidéo) ainsi que la voix de la personne en plus. Le 2a°) restant toutefois préférable au 2b°), tandis que le 1°) est toujours indispensable dans tous les cas. + +3°) D'avoir bien vérifié avec la personne concernée qu'elle a bien généré son document Duniter de révocation de compte, qui lui permettra le cas échéant de pouvoir annuler son compte (cas d'un vol de compte, d'un changement de ID, d'un compte créé à tort etc.). + +**Règles abrégées de la TdC :** + +Chaque membre a un stock de 100 certifications possibles, qu'il ne peut émettre qu'au rythme de 1 certification / 5 jours. + +Valable 2 mois, une certification pour un nouveau membre n'est définitivement adoptée que si le certifié possède au moins 4 autres certifications au bout de ces 2 mois, sinon le processus d'entrée devra être relancé. + +Pour devenir un nouveau membre de la TdC Ğ1 il faut donc obtenir 5 certifications est ne pas se trouver à une distance > 5 de 80% des membres référents de la TdC. + +Un membre de la TdC Ğ1 est membre référent lorsqu'il a reçu et émis au moins Y[N] certifications où N est le nombre de membres de la TdC et Y[N] = plafond N^(1/5). Exemples : + +* Pour 1024 < N ≤ 3125 on a Y[N] = 5 +* Pour 7776 < N ≤ 16807 on a Y[N] = 7 +* pour 59049 < N ≤ 100 000 on a Y[N] = 10 + +Une fois que le nouveau membre est partie prenante de la TdC Ğ1 ses certifications restent valables 2 ans. + +Pour rester membre il faut renouveler son accord régulièrement avec sa clé privée (tous les 12 mois) et s'assurer d'avoir toujours au moins 5 certifications valides au delà des 2 ans. + +Logiciels Ğ1 et licence Ğ1 +-------------------------- + +Les logiciels Ğ1 permettant aux utilisateurs de gérer leur utilisation de Ğ1 doivent transmettre cette licence avec le logiciel ainsi que l'ensemble des paramètres techniques de la monnaie Ğ1 et de la TdC Ğ1 qui sont inscrits dans le bloc 0 de Ğ1. + +Pour plus de précisions dans les détails techniques il est possible de consulter directement le code de Duniter qui est un logiciel libre ansi que les données de la blockchain Ğ1 en la récupérant via une instance (ou noeud) Duniter Ğ1. + +Plus d'informations sur le site de l'équipe Duniter https://www.duniter.org diff --git a/www/templates/currency/modal_license.html b/www/templates/currency/modal_license.html index 316074c7e..3e3483b5b 100644 --- a/www/templates/currency/modal_license.html +++ b/www/templates/currency/modal_license.html @@ -16,7 +16,7 @@ ng-if="licenseUrl && !loading" class="padding-left padding-right no-padding-xs iframe-license" id="iframe-license" - ng-src="{{licenseUrl}}"> + ng-src="{{licenseUrlHtml||licenseUrl}}"> </iframe> <div class="padding hidden-xs text-center"> -- GitLab