mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-01 00:58:53 +02:00
Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
57
Gruntfile.js
57
Gruntfile.js
@@ -1,24 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
var fork = require('child_process').fork,
|
||||
env = process.env,
|
||||
worker, updateWorker,
|
||||
incomplete = [],
|
||||
running = 0;
|
||||
|
||||
var fork = require('child_process').fork;
|
||||
var env = process.env;
|
||||
var worker, updateWorker, initWorker;
|
||||
var incomplete = [];
|
||||
var running = 0;
|
||||
|
||||
module.exports = function (grunt) {
|
||||
var args = [];
|
||||
var initArgs = ['--build'];
|
||||
if (!grunt.option('verbose')) {
|
||||
args.push('--log-level=info');
|
||||
initArgs.push('--log-level=info');
|
||||
}
|
||||
|
||||
function update(action, filepath, target) {
|
||||
var updateArgs = args.slice(),
|
||||
fromFile = '',
|
||||
compiling = '',
|
||||
time = Date.now();
|
||||
|
||||
var updateArgs = args.slice();
|
||||
var compiling = '';
|
||||
var time = Date.now();
|
||||
|
||||
if (target === 'lessUpdated_Client') {
|
||||
compiling = 'clientCSS';
|
||||
} else if (target === 'lessUpdated_Admin') {
|
||||
@@ -44,12 +44,16 @@ module.exports = function (grunt) {
|
||||
if (updateWorker) {
|
||||
updateWorker.kill('SIGKILL');
|
||||
}
|
||||
updateWorker = fork('app.js', updateArgs, { env: env });
|
||||
updateWorker = fork('app.js', updateArgs, {
|
||||
env: env
|
||||
});
|
||||
++running;
|
||||
updateWorker.on('exit', function () {
|
||||
--running;
|
||||
if (running === 0) {
|
||||
worker = fork('app.js', args, { env: env });
|
||||
worker = fork('app.js', args, {
|
||||
env: env
|
||||
});
|
||||
worker.on('message', function () {
|
||||
if (incomplete.length) {
|
||||
incomplete = [];
|
||||
@@ -131,15 +135,24 @@ module.exports = function (grunt) {
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
|
||||
if (grunt.option('skip')) {
|
||||
grunt.registerTask('default', ['watch:serverUpdated']);
|
||||
} else {
|
||||
grunt.registerTask('default', ['watch']);
|
||||
}
|
||||
|
||||
|
||||
grunt.registerTask('default', ['watch']);
|
||||
env.NODE_ENV = 'development';
|
||||
|
||||
worker = fork('app.js', args, { env: env });
|
||||
if (grunt.option('skip')) {
|
||||
worker = fork('app.js', args, {
|
||||
env: env
|
||||
});
|
||||
} else {
|
||||
initWorker = fork('app.js', initArgs, {
|
||||
env: env
|
||||
});
|
||||
|
||||
initWorker.on('exit', function () {
|
||||
worker = fork('app.js', args, {
|
||||
env: env
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
grunt.event.on('watch', update);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"loading": "Načítání motivů…",
|
||||
"homepage": "Homepage",
|
||||
"select-skin": "Select Skin",
|
||||
"current-skin": "Current Skin",
|
||||
"skin-updated": "Skin Updated",
|
||||
"homepage": "Domovská stránka",
|
||||
"select-skin": "Vyber motiv",
|
||||
"current-skin": "Současný motiv",
|
||||
"skin-updated": "Motiv aktualizován",
|
||||
"applied-success": "%1 skin was succesfully applied",
|
||||
"revert-success": "Skin reverted to base colours"
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"authentication": "Authentication",
|
||||
"allow-local-login": "Allow local login",
|
||||
"require-email-confirmation": "Require Email Confirmation",
|
||||
"authentication": "Ověření",
|
||||
"allow-local-login": "Povolit místní přihlášení",
|
||||
"require-email-confirmation": "Vyžadovat potvrzení e-mailem",
|
||||
"email-confirm-interval": "User may not resend a confirmation email until",
|
||||
"email-confirm-email2": "minutes have elapsed",
|
||||
"email-confirm-email2": "minut uplynulo",
|
||||
"allow-login-with": "Allow login with",
|
||||
"allow-login-with.username-email": "Username or Email",
|
||||
"allow-login-with.username": "Username Only",
|
||||
"allow-login-with.email": "Email Only",
|
||||
"account-settings": "Account Settings",
|
||||
"disable-username-changes": "Disable username changes",
|
||||
"disable-email-changes": "Disable email changes",
|
||||
"disable-password-changes": "Disable password changes",
|
||||
"allow-account-deletion": "Allow account deletion",
|
||||
"allow-login-with.username-email": "Uživatelské jméno nebo e-mail",
|
||||
"allow-login-with.username": "Pouze uživatelské jméno",
|
||||
"allow-login-with.email": "Pouze e-mail",
|
||||
"account-settings": "Nastavení účtu",
|
||||
"disable-username-changes": "Zakázat změnu uživatelského jména",
|
||||
"disable-email-changes": "Zakázat změnu e-mailu",
|
||||
"disable-password-changes": "Zakázat změnu hesla",
|
||||
"allow-account-deletion": "Povolit smazání účtu",
|
||||
"user-info-private": "Make user info private",
|
||||
"themes": "Themes",
|
||||
"disable-user-skins": "Prevent users from choosing a custom skin",
|
||||
"themes": "Témata",
|
||||
"disable-user-skins": "Zabránit uživateli ve výběru vlastního vzhledu",
|
||||
"account-protection": "Account Protection",
|
||||
"login-attempts": "Login attempts per hour",
|
||||
"login-attempts-help": "If login attempts to a user's account exceeds this threshold, that account will be locked for a pre-configured amount of time",
|
||||
@@ -34,10 +34,10 @@
|
||||
"registration.max-invites": "Maximum Invitations per User",
|
||||
"max-invites": "Maximum Invitations per User",
|
||||
"max-invites-help": "0 for no restriction. Admins get infinite invitations<br>Only applicable for \"Invite Only\"",
|
||||
"min-username-length": "Minimum Username Length",
|
||||
"max-username-length": "Maximum Username Length",
|
||||
"min-password-length": "Minimum Password Length",
|
||||
"max-about-me-length": "Maximum About Me Length",
|
||||
"min-username-length": "Minimální délka uživatelského jména",
|
||||
"max-username-length": "Maximální délka uživatelského jména",
|
||||
"min-password-length": "Minimální délka hesla",
|
||||
"max-about-me-length": "Maximální délka hesla",
|
||||
"terms-of-use": "Forum Terms of Use <small>(Leave blank to disable)</small>",
|
||||
"user-search": "User Search",
|
||||
"user-search-results-per-page": "Number of results to display",
|
||||
@@ -48,10 +48,10 @@
|
||||
"outgoing-new-tab": "Open outgoing links in new tab",
|
||||
"topic-search": "Enable In-Topic Searching",
|
||||
"digest-freq": "Subscribe to Digest",
|
||||
"digest-freq.off": "Off",
|
||||
"digest-freq.daily": "Daily",
|
||||
"digest-freq.weekly": "Weekly",
|
||||
"digest-freq.monthly": "Monthly",
|
||||
"digest-freq.off": "Vypnuto",
|
||||
"digest-freq.daily": "Denně",
|
||||
"digest-freq.weekly": "Týdně",
|
||||
"digest-freq.monthly": "Měsíčně",
|
||||
"email-chat-notifs": "Send an email if a new chat message arrives and I am not online",
|
||||
"email-post-notif": "Send an email when replies are made to topics I am subscribed to",
|
||||
"follow-created-topics": "Follow topics you create",
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
"failed_login_attempt": "Přihlášení neúspěšné",
|
||||
"login_successful": "Přihlášení proběhlo úspěšně!",
|
||||
"dont_have_account": "Nemáte účet?",
|
||||
"logged-out-due-to-inactivity": "You have been logged out of the Admin Control Panel due to inactivity"
|
||||
"logged-out-due-to-inactivity": "Z důvodu nečinnosti jste byl odhlášen z ovládacího panelu administrátora"
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
"chat.contacts": "Kontakty",
|
||||
"chat.message-history": "Historie zpráv",
|
||||
"chat.pop-out": "Skrýt chat",
|
||||
"chat.minimize": "Minimize",
|
||||
"chat.minimize": "Minimalizovat",
|
||||
"chat.maximize": "Maximalizovat",
|
||||
"chat.seven_days": "7 dní",
|
||||
"chat.thirty_days": "30 dní",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"register": "Registrace",
|
||||
"cancel_registration": "Cancel Registration",
|
||||
"cancel_registration": "Zrušit registraci",
|
||||
"help.email": "Ve výchozím nastavení bude váš e-mail skrytý.",
|
||||
"help.username_restrictions": "Jedinečné uživatelské jméno dlouhé %1 až %2 znaků. Ostatní uživatelé Vás mohou zmínit jako @<span id='yourUsername'>uživatelské-jméno</span>.",
|
||||
"help.minimum_password_length": "Délka vašeho hesla musí být alespoň %1 znaků.",
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"topics_per_page": "Témat na stránce",
|
||||
"posts_per_page": "Příspěvků na stránce",
|
||||
"notification_sounds": "Přehrát zvuk když dostanete notifikaci",
|
||||
"notifications_and_sounds": "Notifications & Sounds",
|
||||
"notifications_and_sounds": "Upozornění a zvuky",
|
||||
"incoming-message-sound": "Incoming message sound",
|
||||
"outgoing-message-sound": "Outgoing message sound",
|
||||
"notification-sound": "Notification sound",
|
||||
|
||||
@@ -107,10 +107,10 @@
|
||||
"more_guests": "ゲストさんが%1人",
|
||||
"users_and_others": "%1と他は%2",
|
||||
"sort_by": "並び替え",
|
||||
"oldest_to_newest": "新しい順に",
|
||||
"newest_to_oldest": "古い順に",
|
||||
"most_votes": "最高評価",
|
||||
"most_posts": "最高投稿",
|
||||
"oldest_to_newest": "古い\bものから新しい順",
|
||||
"newest_to_oldest": "新しいものから古い順",
|
||||
"most_votes": "最も投票された順",
|
||||
"most_posts": "最も投稿された順",
|
||||
"stale.title": "新しいスレッドを作りますか?",
|
||||
"stale.warning": "あなたが返信しようとしてるスレッドが古いスレッドです。新しいスレッドを作って、そしてこのスレッドが参考として入れた方を勧めます。そうしますか?",
|
||||
"stale.create": "新しいスレッドを作ります。",
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"figure-x": "Znázorniť %1",
|
||||
"error-events-per-day": "<code>%1</code> events per day",
|
||||
"error.404": "404 Not Found",
|
||||
"error.503": "503 Service Unavailable",
|
||||
"error.404": "404 Nenájdené",
|
||||
"error.503": "503 Služba nie je k dispozícií",
|
||||
"manage-error-log": "Manage Error Log",
|
||||
"export-error-log": "Export Error Log (CSV)",
|
||||
"clear-error-log": "Clear Error Log",
|
||||
"route": "Route",
|
||||
"count": "Count",
|
||||
"no-routes-not-found": "Hooray! No 404 errors!",
|
||||
"no-routes-not-found": "Hurá! Žiadne chyby 404!",
|
||||
"clear404-confirm": "Are you sure you wish to clear the 404 error logs?",
|
||||
"clear404-success": "\"404 Not Found\" errors cleared"
|
||||
"clear404-success": "Chybné hlásenia \"404 Nenájdené\" vyčistené"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"events": "Udalosti",
|
||||
"no-events": "There are no events",
|
||||
"control-panel": "Events Control Panel",
|
||||
"delete-events": "Delete Events"
|
||||
"no-events": "Zatiaľ neexistujô žiadne udalosti",
|
||||
"control-panel": "Ovládací panel udalostí",
|
||||
"delete-events": "Odstrániť udalosť"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"logs": "Protokoly",
|
||||
"control-panel": "Logs Control Panel",
|
||||
"reload": "Reload Logs",
|
||||
"clear": "Clear Logs",
|
||||
"clear-success": "Logs Cleared!"
|
||||
"logs": "Záznamy",
|
||||
"control-panel": "Ovládací panel záznamov",
|
||||
"reload": "Znovu načítať záznamy",
|
||||
"clear": "Vyčistiť záznamy",
|
||||
"clear-success": "Záznamy vyčistené!"
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"loading": "Loading Skins...",
|
||||
"homepage": "Homepage",
|
||||
"select-skin": "Select Skin",
|
||||
"current-skin": "Current Skin",
|
||||
"skin-updated": "Skin Updated",
|
||||
"applied-success": "%1 skin was succesfully applied",
|
||||
"revert-success": "Skin reverted to base colours"
|
||||
"loading": "Načítať vzhľady...",
|
||||
"homepage": "Domovska stránka",
|
||||
"select-skin": "Vybrať vzhľad",
|
||||
"current-skin": "Aktuálny vzhľad",
|
||||
"skin-updated": "Vzhľad aktualizovaný",
|
||||
"applied-success": "%1 vzhľad bol úspešne aplikovaný",
|
||||
"revert-success": "Vzhľad bol obnovený do základných farieb"
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"checking-for-installed": "Checking for installed themes...",
|
||||
"homepage": "Homepage",
|
||||
"select-theme": "Select Theme",
|
||||
"current-theme": "Current Theme",
|
||||
"no-themes": "No installed themes found",
|
||||
"revert-confirm": "Are you sure you wish to restore the default NodeBB theme?",
|
||||
"theme-changed": "Theme Changed",
|
||||
"revert-success": "You have successfully reverted your NodeBB back to it's default theme.",
|
||||
"restart-to-activate": "Please restart your NodeBB to fully activate this theme"
|
||||
"checking-for-installed": "Kontrola nainštalovaných motívov...",
|
||||
"homepage": "Domovská stránka",
|
||||
"select-theme": "Vybrať motív",
|
||||
"current-theme": "Aktuálny motív",
|
||||
"no-themes": "Žiadne nainštalované motívy neboli nájdené",
|
||||
"revert-confirm": "Ste si istý, že chcete obnoviť predvolený NodeBB motív?",
|
||||
"theme-changed": "Motív zmenený",
|
||||
"revert-success": "Úspešne sa Vám podarilo obnoviť Váš NodeBB do predvoleného motívu.",
|
||||
"restart-to-activate": "Prosím, reštartujte Váš NodeBB pre úplne aktivovanie tohto motívu."
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"forum-traffic": "Forum Traffic",
|
||||
"page-views": "Page Views",
|
||||
"unique-visitors": "Unique Visitors",
|
||||
"users": "Users",
|
||||
"posts": "Posts",
|
||||
"topics": "Topics",
|
||||
"page-views-last-month": "Page views Last Month",
|
||||
"page-views-this-month": "Page views This Month",
|
||||
"page-views-last-day": "Page views in last 24 hours",
|
||||
"forum-traffic": "Prevádzka fóra",
|
||||
"page-views": "Zobrazenia stránok",
|
||||
"unique-visitors": "Unikátne návštevy",
|
||||
"users": "Užívatelia",
|
||||
"posts": "Príspevky",
|
||||
"topics": "Témy",
|
||||
"page-views-last-month": "Zobrazenia stránok za posledný mesiac",
|
||||
"page-views-this-month": "Zobrazenia stránok za tento mesiac",
|
||||
"page-views-last-day": "Zobrazenia stránok za posledných 24 hodín",
|
||||
|
||||
"stats.day": "Day",
|
||||
"stats.week": "Week",
|
||||
"stats.month": "Month",
|
||||
"stats.all": "All Time",
|
||||
"stats.day": "Deň",
|
||||
"stats.week": "Týždeň",
|
||||
"stats.month": "Mesiac",
|
||||
"stats.all": "Celé obdobie",
|
||||
|
||||
"updates": "Updates",
|
||||
"updates": "Aktualizácie",
|
||||
"running-version": "You are running <strong>NodeBB v<span id=\"version\">%1</span></strong>.",
|
||||
"keep-updated": "Always make sure that your NodeBB is up to date for the latest security patches and bug fixes.",
|
||||
"up-to-date": "<p>You are <strong>up-to-date</strong> <i class=\"fa fa-check\"></i></p>",
|
||||
@@ -22,42 +22,42 @@
|
||||
"prerelease-upgrade-available": "<p>This is an outdated pre-release version of NodeBB. A new version (v%1) has been released. Consider <a href=\"https://docs.nodebb.org/en/latest/upgrading/index.html\">upgrading your NodeBB</a>.</p>",
|
||||
"prerelease-warning": "<p>This is a <strong>pre-release</strong> version of NodeBB. Unintended bugs may occur. <i class=\"fa fa-exclamation-triangle\"></i></p>",
|
||||
|
||||
"notices": "Notices",
|
||||
"restart-not-required": "Restart not required",
|
||||
"restart-required": "Restart required",
|
||||
"search-plugin-installed": "Search Plugin installed",
|
||||
"search-plugin-not-installed": "Search Plugin not installed",
|
||||
"notices": "Upozornenie",
|
||||
"restart-not-required": "Reštart nie je potrebný",
|
||||
"restart-required": "Reštart je potrebný",
|
||||
"search-plugin-installed": "Vyhľadávací doplnok bol nainštalovaný",
|
||||
"search-plugin-not-installed": "Vyhľadávací doplnok nebol nainštalovaný",
|
||||
"search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality",
|
||||
|
||||
"control-panel": "System Control",
|
||||
"reload": "Reload",
|
||||
"restart": "Restart",
|
||||
"reload": "Obnoviť",
|
||||
"restart": "Reštartovať",
|
||||
"restart-warning": "Reloading or Restarting your NodeBB will drop all existing connections for a few seconds.",
|
||||
"maintenance-mode": "Maintenance Mode",
|
||||
"maintenance-mode-title": "Click here to set up maintenance mode for NodeBB",
|
||||
"realtime-chart-updates": "Realtime Chart Updates",
|
||||
|
||||
"active-users": "Active Users",
|
||||
"active-users.users": "Users",
|
||||
"active-users.guests": "Guests",
|
||||
"active-users.total": "Total",
|
||||
"active-users.connections": "Connections",
|
||||
"active-users": "Aktívny užívatelia",
|
||||
"active-users.users": "Užívatelia",
|
||||
"active-users.guests": "Hostia",
|
||||
"active-users.total": "Celkovo",
|
||||
"active-users.connections": "Pripojení",
|
||||
|
||||
"anonymous-registered-users": "Anonymous vs Registered Users",
|
||||
"anonymous": "Anonymous",
|
||||
"registered": "Registered",
|
||||
"anonymous-registered-users": "Neznámy vs Zaregistrovaný užívatelia",
|
||||
"anonymous": "Neznámy",
|
||||
"registered": "Zaregistrovaný",
|
||||
|
||||
"user-presence": "User Presence",
|
||||
"on-categories": "On categories list",
|
||||
"reading-posts": "Reading posts",
|
||||
"browsing-topics": "Browsing topics",
|
||||
"recent": "Recent",
|
||||
"unread": "Unread",
|
||||
"recent": "Nedávne",
|
||||
"unread": "Neprečitané",
|
||||
|
||||
"high-presence-topics": "High Presence Topics",
|
||||
|
||||
"graphs.page-views": "Page Views",
|
||||
"graphs.unique-visitors": "Unique Visitors",
|
||||
"graphs.registered-users": "Registered Users",
|
||||
"graphs.anonymous-users": "Anonymous Users"
|
||||
"graphs.page-views": "Zobrazenia stránok",
|
||||
"graphs.unique-visitors": "Unikátny navštevníci",
|
||||
"graphs.registered-users": "Zarestrovaný užívatelia",
|
||||
"graphs.anonymous-users": "Neznámy užívatelia"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"description": "Select tags via clicking and/or dragging, use shift to select multiple.",
|
||||
"create": "Create Tag",
|
||||
"modify": "Modify Tags",
|
||||
"delete": "Delete Selected Tags",
|
||||
"delete": "Odstrániť vybraté značky",
|
||||
"search": "Search for tags...",
|
||||
"settings": "Click <a href=\"%1\">here</a> to visit the tag settings page.",
|
||||
"name": "Tag Name",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"posts": "İletiler",
|
||||
"allow-files": "Allow users to upload regular files",
|
||||
"private": "Make uploaded files private",
|
||||
"private": "Yüklenen dosyaları gizli yap",
|
||||
"max-image-width": "Resize images down to specified width (in pixels)",
|
||||
"max-image-width-help": "(in pixels, default: 760 pixels, set to 0 to disable)",
|
||||
"max-file-size": "Maksimum Dosya Boyutu (KiB)",
|
||||
@@ -19,10 +19,10 @@
|
||||
"profile-image-dimension-help": "(in pixels, default: 128 pixels)",
|
||||
"max-profile-image-size": "Maximum Profile Image File Size",
|
||||
"max-profile-image-size-help": "(in kilobytes, default: 256 KiB)",
|
||||
"max-cover-image-size": "Maximum Cover Image File Size",
|
||||
"max-cover-image-size": "Maksimum Kapak Görseli Dosya Boyutu",
|
||||
"max-cover-image-size-help": "(in kilobytes, default: 2,048 KiB)",
|
||||
"keep-all-user-images": "Keep old versions of avatars and profile covers on the server",
|
||||
"profile-covers": "Profile Covers",
|
||||
"default-covers": "Default Cover Images",
|
||||
"profile-covers": "Profil Kapakları",
|
||||
"default-covers": "Varsayılan Kapak Görseli",
|
||||
"default-covers-help": "Add comma-separated default cover images for accounts that don't have an uploaded cover image"
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ define('pictureCropper', ['translator', 'cropper'], function (translator, croppe
|
||||
uploadModal = $(uploadModal);
|
||||
|
||||
uploadModal.modal('show');
|
||||
uploadModal.on('hidden.bs.modal', function () {
|
||||
uploadModal.on('hidden.bs.modal', function () {
|
||||
uploadModal.remove();
|
||||
});
|
||||
|
||||
@@ -31,9 +31,11 @@ define('pictureCropper', ['translator', 'cropper'], function (translator, croppe
|
||||
});
|
||||
};
|
||||
|
||||
module.handleImageCrop = function (data, callback) {
|
||||
module.handleImageCrop = function (data, callback) {
|
||||
$('#crop-picture-modal').remove();
|
||||
templates.parse('modals/crop_picture', {url: data.url}, function (cropperHtml) {
|
||||
templates.parse('modals/crop_picture', {
|
||||
url: data.url
|
||||
}, function (cropperHtml) {
|
||||
translator.translate(cropperHtml, function (translated) {
|
||||
var cropperModal = $(translated);
|
||||
cropperModal.modal('show');
|
||||
@@ -58,28 +60,28 @@ define('pictureCropper', ['translator', 'cropper'], function (translator, croppe
|
||||
cropperModal.find('.reset').on('click', function () {
|
||||
cropperTool.reset();
|
||||
});
|
||||
|
||||
|
||||
cropperModal.find('.crop-btn').on('click', function () {
|
||||
$(this).addClass('disabled');
|
||||
var imageData = data.imageType ? cropperTool.getCroppedCanvas().toDataURL(data.imageType) : cropperTool.getCroppedCanvas().toDataURL();
|
||||
|
||||
|
||||
cropperModal.find('#upload-progress-bar').css('width', '100%');
|
||||
cropperModal.find('#upload-progress-box').show().removeClass('hide');
|
||||
|
||||
|
||||
var socketData = {};
|
||||
socketData[data.paramName] = data.paramValue;
|
||||
socketData['imageData'] = imageData;
|
||||
|
||||
socket.emit(data.socketMethod, socketData, function (err, imageData) {
|
||||
if (err) {
|
||||
cropperModal.find('#upload-progress-box').hide();
|
||||
cropperModal.find('.upload-btn').removeClass('disabled');
|
||||
cropperModal.find('.crop-btn').removeClass('disabled');
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
callback(imageData.url);
|
||||
cropperModal.modal('hide');
|
||||
socket.emit(data.socketMethod, socketData, function (err, imageData) {
|
||||
if (err) {
|
||||
cropperModal.find('#upload-progress-box').hide();
|
||||
cropperModal.find('.upload-btn').removeClass('disabled');
|
||||
cropperModal.find('.crop-btn').removeClass('disabled');
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
callback(imageData.url);
|
||||
cropperModal.modal('hide');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -115,8 +117,8 @@ define('pictureCropper', ['translator', 'cropper'], function (translator, croppe
|
||||
return showAlert('error', '[[uploads:select-file-to-upload]]');
|
||||
}
|
||||
|
||||
var file = fileInput[0].files[0];
|
||||
var reader = new FileReader();
|
||||
var file = fileInput[0].files[0];
|
||||
var reader = new FileReader();
|
||||
var imageUrl;
|
||||
var imageType = file.type;
|
||||
|
||||
|
||||
@@ -59,7 +59,10 @@ function uploadAsImage(req, uploadedFile, callback) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: uploadedFile, uid: req.uid}, callback);
|
||||
return plugins.fireHook('filter:uploadImage', {
|
||||
image: uploadedFile,
|
||||
uid: req.uid
|
||||
}, callback);
|
||||
}
|
||||
file.isFileTypeAllowed(uploadedFile.path, next);
|
||||
},
|
||||
@@ -156,7 +159,10 @@ uploadsController.uploadThumb = function (req, res, next) {
|
||||
}
|
||||
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: uploadedFile, uid: req.uid}, next);
|
||||
return plugins.fireHook('filter:uploadImage', {
|
||||
image: uploadedFile,
|
||||
uid: req.uid
|
||||
}, next);
|
||||
}
|
||||
|
||||
uploadFile(req.uid, uploadedFile, next);
|
||||
@@ -167,11 +173,17 @@ uploadsController.uploadThumb = function (req, res, next) {
|
||||
|
||||
uploadsController.uploadGroupCover = function (uid, uploadedFile, callback) {
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: uploadedFile, uid: uid}, callback);
|
||||
return plugins.fireHook('filter:uploadImage', {
|
||||
image: uploadedFile,
|
||||
uid: uid
|
||||
}, callback);
|
||||
}
|
||||
|
||||
if (plugins.hasListeners('filter:uploadFile')) {
|
||||
return plugins.fireHook('filter:uploadFile', {file: uploadedFile, uid: uid}, callback);
|
||||
return plugins.fireHook('filter:uploadFile', {
|
||||
file: uploadedFile,
|
||||
uid: uid
|
||||
}, callback);
|
||||
}
|
||||
|
||||
file.isFileTypeAllowed(uploadedFile.path, function (err) {
|
||||
@@ -184,7 +196,10 @@ uploadsController.uploadGroupCover = function (uid, uploadedFile, callback) {
|
||||
|
||||
function uploadFile(uid, uploadedFile, callback) {
|
||||
if (plugins.hasListeners('filter:uploadFile')) {
|
||||
return plugins.fireHook('filter:uploadFile', {file: uploadedFile, uid: uid}, callback);
|
||||
return plugins.fireHook('filter:uploadFile', {
|
||||
file: uploadedFile,
|
||||
uid: uid
|
||||
}, callback);
|
||||
}
|
||||
|
||||
if (!uploadedFile) {
|
||||
@@ -197,7 +212,7 @@ function uploadFile(uid, uploadedFile, callback) {
|
||||
|
||||
if (meta.config.hasOwnProperty('allowedFileExtensions')) {
|
||||
var allowed = file.allowedExtensions();
|
||||
var extension = typeToExtension(uploadedFile.type);
|
||||
var extension = file.typeToExtension(uploadedFile.type);
|
||||
if (!extension || (allowed.length > 0 && allowed.indexOf(extension) === -1)) {
|
||||
return callback(new Error('[[error:invalid-file-type, ' + allowed.join(', ') + ']]'));
|
||||
}
|
||||
@@ -207,7 +222,7 @@ function uploadFile(uid, uploadedFile, callback) {
|
||||
}
|
||||
|
||||
function saveFileToLocal(uploadedFile, callback) {
|
||||
var extension = typeToExtension(uploadedFile.type);
|
||||
var extension = file.typeToExtension(uploadedFile.type);
|
||||
if (!extension) {
|
||||
return callback(new Error('[[error:invalid-extension]]'));
|
||||
}
|
||||
@@ -228,14 +243,6 @@ function saveFileToLocal(uploadedFile, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function typeToExtension(type) {
|
||||
var extension;
|
||||
if (type) {
|
||||
extension = '.' + mime.extension(type);
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
|
||||
function deleteTempFiles(files) {
|
||||
async.each(files, function (file, next) {
|
||||
fs.unlink(file.path, function (err) {
|
||||
@@ -247,6 +254,4 @@ function deleteTempFiles(files) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
module.exports = uploadsController;
|
||||
|
||||
16
src/file.js
16
src/file.js
@@ -6,6 +6,7 @@ var path = require('path');
|
||||
var winston = require('winston');
|
||||
var jimp = require('jimp');
|
||||
var mkdirp = require('mkdirp');
|
||||
var mime = require('mime');
|
||||
|
||||
var utils = require('../public/src/utils');
|
||||
|
||||
@@ -13,8 +14,8 @@ var file = {};
|
||||
|
||||
file.saveFileToLocal = function (filename, folder, tempPath, callback) {
|
||||
/*
|
||||
* remarkable doesn't allow spaces in hyperlinks, once that's fixed, remove this.
|
||||
*/
|
||||
* remarkable doesn't allow spaces in hyperlinks, once that's fixed, remove this.
|
||||
*/
|
||||
filename = filename.split('.');
|
||||
filename.forEach(function (name, idx) {
|
||||
filename[idx] = utils.slugify(name);
|
||||
@@ -118,7 +119,8 @@ file.existsSync = function (path) {
|
||||
file.link = function link(filePath, destPath, cb) {
|
||||
if (process.platform === 'win32') {
|
||||
fs.link(filePath, destPath, cb);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
fs.symlink(filePath, destPath, 'file', cb);
|
||||
}
|
||||
};
|
||||
@@ -128,4 +130,12 @@ file.linkDirs = function linkDirs(sourceDir, destDir, callback) {
|
||||
fs.symlink(sourceDir, destDir, type, callback);
|
||||
};
|
||||
|
||||
file.typeToExtension = function (type) {
|
||||
var extension;
|
||||
if (type) {
|
||||
extension = '.' + mime.extension(type);
|
||||
}
|
||||
return extension;
|
||||
};
|
||||
|
||||
module.exports = file;
|
||||
|
||||
@@ -10,6 +10,7 @@ var mime = require('mime');
|
||||
var winston = require('winston');
|
||||
|
||||
var db = require('../database');
|
||||
var image = require('../image');
|
||||
var uploadsController = require('../controllers/uploads');
|
||||
|
||||
module.exports = function (Groups) {
|
||||
@@ -37,7 +38,7 @@ module.exports = function (Groups) {
|
||||
if (tempPath) {
|
||||
return next(null, tempPath);
|
||||
}
|
||||
writeImageDataToFile(data.imageData, next);
|
||||
image.writeImageDataToTempFile(data.imageData, next);
|
||||
},
|
||||
function (_tempPath, next) {
|
||||
tempPath = _tempPath;
|
||||
@@ -97,24 +98,6 @@ module.exports = function (Groups) {
|
||||
});
|
||||
}
|
||||
|
||||
function writeImageDataToFile(imageData, callback) {
|
||||
// Calculate md5sum of image
|
||||
// This is required because user data can be private
|
||||
var md5sum = crypto.createHash('md5');
|
||||
md5sum.update(imageData);
|
||||
md5sum = md5sum.digest('hex');
|
||||
|
||||
// Save image
|
||||
var tempPath = path.join(nconf.get('upload_path'), md5sum + '.png');
|
||||
var buffer = new Buffer(imageData.slice(imageData.indexOf('base64') + 7), 'base64');
|
||||
|
||||
fs.writeFile(tempPath, buffer, {
|
||||
encoding: 'base64'
|
||||
}, function (err) {
|
||||
callback(err, tempPath);
|
||||
});
|
||||
}
|
||||
|
||||
Groups.removeCover = function (data, callback) {
|
||||
db.deleteObjectFields('group:' + data.groupName, ['cover:url', 'cover:thumb:url', 'cover:position'], callback);
|
||||
};
|
||||
|
||||
37
src/image.js
37
src/image.js
@@ -1,8 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var os = require('os');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var Jimp = require('jimp');
|
||||
var async = require('async');
|
||||
var crypto = require('crypto');
|
||||
|
||||
var file = require('./file');
|
||||
var plugins = require('./plugins');
|
||||
|
||||
var image = module.exports;
|
||||
@@ -65,9 +70,6 @@ image.resizeImage = function (data, callback) {
|
||||
}
|
||||
},
|
||||
function (image, next) {
|
||||
if (data.write === false) {
|
||||
return next();
|
||||
}
|
||||
image.write(data.target || data.path, next);
|
||||
}
|
||||
], function (err) {
|
||||
@@ -83,7 +85,7 @@ image.normalise = function (path, extension, callback) {
|
||||
path: path,
|
||||
extension: extension
|
||||
}, function (err) {
|
||||
callback(err);
|
||||
callback(err, path + '.png');
|
||||
});
|
||||
} else {
|
||||
new Jimp(path, function (err, image) {
|
||||
@@ -91,7 +93,7 @@ image.normalise = function (path, extension, callback) {
|
||||
return callback(err);
|
||||
}
|
||||
image.write(path + '.png', function (err) {
|
||||
callback(err);
|
||||
callback(err, path + '.png');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -116,3 +118,28 @@ image.convertImageToBase64 = function (path, callback) {
|
||||
callback(err, data ? data.toString('base64') : null);
|
||||
});
|
||||
};
|
||||
|
||||
image.mimeFromBase64 = function (imageData) {
|
||||
return imageData.slice(5, imageData.indexOf('base64') - 1);
|
||||
};
|
||||
|
||||
image.extensionFromBase64 = function (imageData) {
|
||||
return file.typeToExtension(image.mimeFromBase64(imageData));
|
||||
};
|
||||
|
||||
image.writeImageDataToTempFile = function (imageData, callback) {
|
||||
var filename = crypto.createHash('md5').update(imageData).digest('hex');
|
||||
|
||||
var type = image.mimeFromBase64(imageData);
|
||||
var extension = file.typeToExtension(type);
|
||||
|
||||
var filepath = path.join(os.tmpdir(), filename + extension);
|
||||
|
||||
var buffer = new Buffer(imageData.slice(imageData.indexOf('base64') + 7), 'base64');
|
||||
|
||||
fs.writeFile(filepath, buffer, {
|
||||
encoding: 'base64'
|
||||
}, function (err) {
|
||||
callback(err, filepath);
|
||||
});
|
||||
};
|
||||
@@ -389,8 +389,8 @@ function createMenuItems(next) {
|
||||
if (err || exists) {
|
||||
return next(err);
|
||||
}
|
||||
var navigation = require('./navigation/admin'),
|
||||
data = require('../install/data/navigation.json');
|
||||
var navigation = require('./navigation/admin');
|
||||
var data = require('../install/data/navigation.json');
|
||||
|
||||
navigation.save(data, next);
|
||||
});
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
|
||||
|
||||
var async = require('async');
|
||||
var plugins = require('../plugins');
|
||||
var db = require('../database');
|
||||
var translator = require('../../public/src/modules/translator');
|
||||
var pubsub = require('../pubsub');
|
||||
|
||||
var admin = {};
|
||||
var admin = module.exports;
|
||||
admin.cache = null;
|
||||
|
||||
pubsub.on('admin:navigation:save', function () {
|
||||
@@ -71,5 +69,3 @@ function getAvailable(callback) {
|
||||
|
||||
plugins.fireHook('filter:navigation.available', core, callback);
|
||||
}
|
||||
|
||||
module.exports = admin;
|
||||
@@ -23,9 +23,7 @@ module.exports = function (SocketTopics) {
|
||||
if (!canMove) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
next();
|
||||
},
|
||||
function (next) {
|
||||
|
||||
topics.getTopicFields(tid, ['cid', 'slug'], next);
|
||||
},
|
||||
function (_topicData, next) {
|
||||
|
||||
@@ -272,35 +272,34 @@ SocketUser.invite = function (socket, email, callback) {
|
||||
return callback(new Error('[[error:forum-not-invite-only]]'));
|
||||
}
|
||||
|
||||
var max = meta.config.maximumInvites;
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
user.isAdministrator(socket.uid, next);
|
||||
},
|
||||
function (isAdmin, next) {
|
||||
if (registrationType === 'admin-invite-only' && !isAdmin) {
|
||||
return next(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
var max = parseInt(meta.config.maximumInvites, 10);
|
||||
if (!max) {
|
||||
return user.sendInvitationEmail(socket.uid, email, callback);
|
||||
}
|
||||
|
||||
user.isAdministrator(socket.uid, function (err, admin) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (registrationType === 'admin-invite-only' && !admin) {
|
||||
return callback(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
if (max) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
user.getInvitesNumber(socket.uid, next);
|
||||
},
|
||||
function (invites, next) {
|
||||
if (!admin && invites > max) {
|
||||
if (!isAdmin && invites >= max) {
|
||||
return next(new Error('[[error:invite-maximum-met, ' + invites + ', ' + max + ']]'));
|
||||
}
|
||||
next();
|
||||
},
|
||||
function (next) {
|
||||
|
||||
user.sendInvitationEmail(socket.uid, email, next);
|
||||
}
|
||||
], callback);
|
||||
} else {
|
||||
user.sendInvitationEmail(socket.uid, email, callback);
|
||||
], next);
|
||||
}
|
||||
});
|
||||
|
||||
], callback);
|
||||
};
|
||||
|
||||
SocketUser.getUserByUID = function (socket, uid, callback) {
|
||||
|
||||
@@ -99,6 +99,7 @@ function setupConfigs() {
|
||||
nconf.set('use_port', !!urlObject.port);
|
||||
nconf.set('relative_path', relativePath);
|
||||
nconf.set('port', urlObject.port || nconf.get('port') || nconf.get('PORT') || (nconf.get('PORT_ENV_VAR') ? nconf.get(nconf.get('PORT_ENV_VAR')) : false) || 4567);
|
||||
nconf.set('upload_url', '/assets/uploads');
|
||||
}
|
||||
|
||||
function printStartupInfo() {
|
||||
|
||||
@@ -61,9 +61,7 @@ module.exports = function (User) {
|
||||
if (exists) {
|
||||
return next(new Error('[[error:email-taken]]'));
|
||||
}
|
||||
next();
|
||||
},
|
||||
function (next) {
|
||||
|
||||
async.parallel([
|
||||
function (next) {
|
||||
db.setAdd('invitation:uid:' + uid, email, next);
|
||||
@@ -131,11 +129,11 @@ module.exports = function (User) {
|
||||
return next(new Error('[[error:invalid-username]]'));
|
||||
}
|
||||
async.parallel([
|
||||
function deleteFromReferenceList(next) {
|
||||
db.setRemove('invitation:uid:' + invitedByUid, email, next);
|
||||
function (next) {
|
||||
deleteFromReferenceList(invitedByUid, email, next);
|
||||
},
|
||||
function deleteInviteKey(next) {
|
||||
db.delete('invitation:email:' + email, callback);
|
||||
function (next) {
|
||||
db.delete('invitation:email:' + email, next);
|
||||
}
|
||||
], function (err) {
|
||||
next(err);
|
||||
@@ -146,7 +144,37 @@ module.exports = function (User) {
|
||||
|
||||
User.deleteInvitationKey = function (email, callback) {
|
||||
callback = callback || function () {};
|
||||
db.delete('invitation:email:' + email, callback);
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
User.getInvitingUsers(next);
|
||||
},
|
||||
function (uids, next) {
|
||||
async.each(uids, function (uid, next) {
|
||||
deleteFromReferenceList(uid, email, next);
|
||||
}, next);
|
||||
},
|
||||
function (next) {
|
||||
db.delete('invitation:email:' + email, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
function deleteFromReferenceList(uid, email, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.setRemove('invitation:uid:' + uid, email, next);
|
||||
},
|
||||
function (next) {
|
||||
db.setCount('invitation:uid:' + uid, next);
|
||||
},
|
||||
function (count, next) {
|
||||
if (count === 0) {
|
||||
return db.setRemove('invitation:uids', uid, next);
|
||||
}
|
||||
setImmediate(next);
|
||||
}
|
||||
], callback);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var os = require('os');
|
||||
var nconf = require('nconf');
|
||||
var crypto = require('crypto');
|
||||
var winston = require('winston');
|
||||
var request = require('request');
|
||||
var mime = require('mime');
|
||||
@@ -19,72 +16,7 @@ var db = require('../database');
|
||||
module.exports = function (User) {
|
||||
|
||||
User.uploadPicture = function (uid, picture, callback) {
|
||||
|
||||
var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
|
||||
var extension = path.extname(picture.name);
|
||||
var updateUid = uid;
|
||||
var imageDimension = parseInt(meta.config.profileImageDimension, 10) || 128;
|
||||
var convertToPNG = parseInt(meta.config['profile:convertProfileImageToPNG'], 10) === 1;
|
||||
var keepAllVersions = parseInt(meta.config['profile:keepAllUserImages'], 10) === 1;
|
||||
var uploadedImage;
|
||||
|
||||
if (parseInt(meta.config.allowProfileImageUploads) !== 1) {
|
||||
return callback(new Error('[[error:profile-image-uploads-disabled]]'));
|
||||
}
|
||||
|
||||
if (picture.size > uploadSize * 1024) {
|
||||
return callback(new Error('[[error:file-too-big, ' + uploadSize + ']]'));
|
||||
}
|
||||
|
||||
if (!extension) {
|
||||
return callback(new Error('[[error:invalid-image-extension]]'));
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: picture, uid: updateUid}, next);
|
||||
}
|
||||
|
||||
var filename = updateUid + '-profileimg' + (keepAllVersions ? '-' + Date.now() : '') + (convertToPNG ? '.png' : extension);
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
file.isFileTypeAllowed(picture.path, next);
|
||||
},
|
||||
function (next) {
|
||||
image.resizeImage({
|
||||
path: picture.path,
|
||||
extension: extension,
|
||||
width: imageDimension,
|
||||
height: imageDimension,
|
||||
write: false,
|
||||
}, next);
|
||||
},
|
||||
function (next) {
|
||||
if (!convertToPNG) {
|
||||
return next();
|
||||
}
|
||||
async.series([
|
||||
async.apply(image.normalise, picture.path, extension),
|
||||
async.apply(fs.rename, picture.path + '.png', picture.path)
|
||||
], function (err) {
|
||||
next(err);
|
||||
});
|
||||
},
|
||||
function (next) {
|
||||
file.saveFileToLocal(filename, 'profile', picture.path, next);
|
||||
},
|
||||
], next);
|
||||
},
|
||||
function (_image, next) {
|
||||
uploadedImage = _image;
|
||||
User.setUserFields(updateUid, {uploadedpicture: uploadedImage.url, picture: uploadedImage.url}, next);
|
||||
},
|
||||
function (next) {
|
||||
next(null, uploadedImage);
|
||||
}
|
||||
], callback);
|
||||
User.uploadCroppedPicture({uid: uid, file: picture}, callback);
|
||||
};
|
||||
|
||||
User.uploadFromUrl = function (uid, url, callback) {
|
||||
@@ -92,32 +24,41 @@ module.exports = function (User) {
|
||||
return callback(new Error('[[error:no-plugin]]'));
|
||||
}
|
||||
|
||||
request.head(url, function (err, res) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
|
||||
var size = res.headers['content-length'];
|
||||
var type = res.headers['content-type'];
|
||||
var extension = mime.extension(type);
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
request.head(url, next);
|
||||
},
|
||||
function (res, body, next) {
|
||||
var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
|
||||
var size = res.headers['content-length'];
|
||||
var type = res.headers['content-type'];
|
||||
var extension = mime.extension(type);
|
||||
|
||||
if (['png', 'jpeg', 'jpg', 'gif'].indexOf(extension) === -1) {
|
||||
return callback(new Error('[[error:invalid-image-extension]]'));
|
||||
}
|
||||
|
||||
if (size > uploadSize * 1024) {
|
||||
return callback(new Error('[[error:file-too-big, ' + uploadSize + ']]'));
|
||||
}
|
||||
|
||||
var picture = {url: url, name: ''};
|
||||
plugins.fireHook('filter:uploadImage', {image: picture, uid: uid}, function (err, image) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
if (['png', 'jpeg', 'jpg', 'gif'].indexOf(extension) === -1) {
|
||||
return callback(new Error('[[error:invalid-image-extension]]'));
|
||||
}
|
||||
User.setUserFields(uid, {uploadedpicture: image.url, picture: image.url});
|
||||
callback(null, image);
|
||||
});
|
||||
});
|
||||
|
||||
if (size > uploadSize * 1024) {
|
||||
return callback(new Error('[[error:file-too-big, ' + uploadSize + ']]'));
|
||||
}
|
||||
|
||||
plugins.fireHook('filter:uploadImage', {
|
||||
uid: uid,
|
||||
image: {
|
||||
url: url,
|
||||
name: ''
|
||||
}
|
||||
}, next);
|
||||
},
|
||||
function (image, next) {
|
||||
User.setUserFields(uid, {
|
||||
uploadedpicture: image.url,
|
||||
picture: image.url
|
||||
}, function (err) {
|
||||
next(err, image);
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
User.updateCoverPosition = function (uid, position, callback) {
|
||||
@@ -125,8 +66,12 @@ module.exports = function (User) {
|
||||
};
|
||||
|
||||
User.updateCoverPicture = function (data, callback) {
|
||||
var keepAllVersions = parseInt(meta.config['profile:keepAllUserImages'], 10) === 1;
|
||||
var url, md5sum;
|
||||
|
||||
var url;
|
||||
var picture = {
|
||||
name: 'profileCover',
|
||||
uid: data.uid
|
||||
};
|
||||
|
||||
if (!data.imageData && data.position) {
|
||||
return User.updateCoverPosition(data.uid, data.position, callback);
|
||||
@@ -145,161 +90,165 @@ module.exports = function (User) {
|
||||
}
|
||||
|
||||
if (data.file) {
|
||||
return next();
|
||||
return setImmediate(next, null, data.file.path);
|
||||
}
|
||||
|
||||
md5sum = crypto.createHash('md5');
|
||||
md5sum.update(data.imageData);
|
||||
md5sum = md5sum.digest('hex');
|
||||
|
||||
data.file = {
|
||||
path: path.join(os.tmpdir(), md5sum)
|
||||
};
|
||||
|
||||
var buffer = new Buffer(data.imageData.slice(data.imageData.indexOf('base64') + 7), 'base64');
|
||||
|
||||
fs.writeFile(data.file.path, buffer, {
|
||||
encoding: 'base64'
|
||||
}, next);
|
||||
image.writeImageDataToTempFile(data.imageData, next);
|
||||
},
|
||||
function (next) {
|
||||
var image = {
|
||||
name: 'profileCover',
|
||||
path: data.file.path,
|
||||
uid: data.uid
|
||||
};
|
||||
function (path, next) {
|
||||
picture.path = path;
|
||||
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: image, uid: data.uid}, next);
|
||||
}
|
||||
|
||||
var filename = data.uid + '-profilecover' + (keepAllVersions ? '-' + Date.now() : '');
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
file.isFileTypeAllowed(data.file.path, next);
|
||||
},
|
||||
function (next) {
|
||||
file.saveFileToLocal(filename, 'profile', image.path, next);
|
||||
},
|
||||
function (upload, next) {
|
||||
next(null, {
|
||||
url: nconf.get('relative_path') + upload.url,
|
||||
name: image.name
|
||||
});
|
||||
}
|
||||
], next);
|
||||
var extension = data.file ? file.typeToExtension(data.file.type) : image.extensionFromBase64(data.imageData);
|
||||
var filename = generateProfileImageFilename(data.uid, 'profilecover', extension);
|
||||
uploadProfileOrCover(filename, picture, next);
|
||||
},
|
||||
function (uploadData, next) {
|
||||
url = uploadData.url;
|
||||
User.setUserField(data.uid, 'cover:url', uploadData.url, next);
|
||||
},
|
||||
function (next) {
|
||||
fs.unlink(data.file.path, function (err) {
|
||||
if (err) {
|
||||
winston.error(err);
|
||||
}
|
||||
next();
|
||||
});
|
||||
if (data.position) {
|
||||
User.updateCoverPosition(data.uid, data.position, next);
|
||||
} else {
|
||||
setImmediate(next);
|
||||
}
|
||||
}
|
||||
], function (err) {
|
||||
if (err) {
|
||||
return fs.unlink(data.file.path, function (unlinkErr) {
|
||||
if (unlinkErr) {
|
||||
winston.error(unlinkErr);
|
||||
}
|
||||
|
||||
callback(err); // send back the original error
|
||||
});
|
||||
}
|
||||
|
||||
if (data.position) {
|
||||
User.updateCoverPosition(data.uid, data.position, function (err) {
|
||||
callback(err, {url: url});
|
||||
});
|
||||
} else {
|
||||
callback(err, {url: url});
|
||||
}
|
||||
deleteFile(picture.path);
|
||||
callback(err, {
|
||||
url: url
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
User.uploadCroppedPicture = function (data, callback) {
|
||||
var keepAllVersions = parseInt(meta.config['profile:keepAllUserImages'], 10) === 1;
|
||||
var url, md5sum;
|
||||
|
||||
if (!data.imageData) {
|
||||
User.uploadCroppedPicture = function (data, callback) {
|
||||
|
||||
if (parseInt(meta.config.allowProfileImageUploads) !== 1) {
|
||||
return callback(new Error('[[error:profile-image-uploads-disabled]]'));
|
||||
}
|
||||
|
||||
if (!data.imageData && !data.file) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
|
||||
|
||||
var size = data.file ? data.file.size : data.imageData.length;
|
||||
var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
|
||||
if (size > uploadSize * 1024) {
|
||||
return callback(new Error('[[error:file-too-big, ' + meta.config.maximumProfileImageSize + ']]'));
|
||||
}
|
||||
|
||||
var type = data.file ? data.file.type : image.mimeFromBase64(data.imageData);
|
||||
var extension = file.typeToExtension(type);
|
||||
if (!extension) {
|
||||
return callback(new Error('[[error:invalid-image-extension]]'));
|
||||
}
|
||||
|
||||
var uploadedImage;
|
||||
|
||||
var picture = {
|
||||
name: 'profileAvatar',
|
||||
uid: data.uid
|
||||
};
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
var size = data.file ? data.file.size : data.imageData.length;
|
||||
var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
|
||||
if (size > uploadSize * 1024) {
|
||||
return next(new Error('[[error:file-too-big, ' + meta.config.maximumProfileImageSize + ']]'));
|
||||
if (data.file) {
|
||||
return setImmediate(next, null, data.file.path);
|
||||
}
|
||||
image.writeImageDataToTempFile(data.imageData, next);
|
||||
},
|
||||
function (path, next) {
|
||||
convertToPNG(path, extension, next);
|
||||
},
|
||||
function (path, next) {
|
||||
picture.path = path;
|
||||
|
||||
md5sum = crypto.createHash('md5');
|
||||
md5sum.update(data.imageData);
|
||||
md5sum = md5sum.digest('hex');
|
||||
|
||||
data.file = {
|
||||
path: path.join(os.tmpdir(), md5sum)
|
||||
};
|
||||
|
||||
var buffer = new Buffer(data.imageData.slice(data.imageData.indexOf('base64') + 7), 'base64');
|
||||
|
||||
fs.writeFile(data.file.path, buffer, {
|
||||
encoding: 'base64'
|
||||
var imageDimension = parseInt(meta.config.profileImageDimension, 10) || 128;
|
||||
image.resizeImage({
|
||||
path: picture.path,
|
||||
extension: extension,
|
||||
width: imageDimension,
|
||||
height: imageDimension
|
||||
}, next);
|
||||
},
|
||||
function (next) {
|
||||
var image = {
|
||||
name: 'profileAvatar',
|
||||
path: data.file.path,
|
||||
uid: data.uid
|
||||
};
|
||||
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {image: image, uid: data.uid}, next);
|
||||
}
|
||||
|
||||
var filename = data.uid + '-profileavatar' + (keepAllVersions ? '-' + Date.now() : '');
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
file.isFileTypeAllowed(data.file.path, next);
|
||||
},
|
||||
function (next) {
|
||||
file.saveFileToLocal(filename, 'profile', image.path, next);
|
||||
},
|
||||
function (upload, next) {
|
||||
next(null, {
|
||||
url: nconf.get('relative_path') + upload.url,
|
||||
name: image.name
|
||||
});
|
||||
}
|
||||
], next);
|
||||
var filename = generateProfileImageFilename(data.uid, 'profileavatar', extension);
|
||||
uploadProfileOrCover(filename, picture, next);
|
||||
},
|
||||
function (uploadData, next) {
|
||||
url = uploadData.url;
|
||||
User.setUserFields(data.uid, {uploadedpicture: url, picture: url}, next);
|
||||
},
|
||||
function (next) {
|
||||
fs.unlink(data.file.path, function (err) {
|
||||
if (err) {
|
||||
winston.error(err);
|
||||
}
|
||||
next();
|
||||
});
|
||||
function (_uploadedImage, next) {
|
||||
uploadedImage = _uploadedImage;
|
||||
|
||||
User.setUserFields(data.uid, {
|
||||
uploadedpicture: uploadedImage.url,
|
||||
picture: uploadedImage.url
|
||||
}, next);
|
||||
}
|
||||
], function (err) {
|
||||
if (err) {
|
||||
callback(err); // send back the original error
|
||||
}
|
||||
|
||||
callback(err, {url: url});
|
||||
deleteFile(picture.path);
|
||||
callback(err, uploadedImage);
|
||||
});
|
||||
};
|
||||
|
||||
function convertToPNG(path, extension, callback) {
|
||||
var convertToPNG = parseInt(meta.config['profile:convertProfileImageToPNG'], 10) === 1;
|
||||
if (!convertToPNG) {
|
||||
return setImmediate(callback, null, path);
|
||||
}
|
||||
|
||||
image.normalise(path, extension, function (err, newPath) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
deleteFile(path);
|
||||
callback(null, newPath);
|
||||
});
|
||||
}
|
||||
|
||||
function uploadProfileOrCover(filename, image, callback) {
|
||||
if (plugins.hasListeners('filter:uploadImage')) {
|
||||
return plugins.fireHook('filter:uploadImage', {
|
||||
image: image,
|
||||
uid: image.uid
|
||||
}, callback);
|
||||
}
|
||||
|
||||
saveFileToLocal(filename, image, callback);
|
||||
}
|
||||
|
||||
function generateProfileImageFilename(uid, type, extension) {
|
||||
var keepAllVersions = parseInt(meta.config['profile:keepAllUserImages'], 10) === 1;
|
||||
var convertToPNG = parseInt(meta.config['profile:convertProfileImageToPNG'], 10) === 1;
|
||||
return uid + '-' + type + (keepAllVersions ? '-' + Date.now() : '') + (convertToPNG ? '.png' : extension);
|
||||
}
|
||||
|
||||
function saveFileToLocal(filename, image, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
file.isFileTypeAllowed(image.path, next);
|
||||
},
|
||||
function (next) {
|
||||
file.saveFileToLocal(filename, 'profile', image.path, next);
|
||||
},
|
||||
function (upload, next) {
|
||||
next(null, {
|
||||
url: nconf.get('relative_path') + upload.url,
|
||||
path: upload.path,
|
||||
name: image.name
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
}
|
||||
|
||||
function deleteFile(path) {
|
||||
if (path) {
|
||||
fs.unlink(path, function (err) {
|
||||
if (err) {
|
||||
winston.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
User.removeCoverPicture = function (data, callback) {
|
||||
db.deleteObjectFields('user:' + data.uid, ['cover:url', 'cover:position'], callback);
|
||||
};
|
||||
|
||||
@@ -29,6 +29,12 @@ describe('Controllers', function () {
|
||||
},
|
||||
user: function (next) {
|
||||
user.create({username: 'foo', password: 'barbar'}, next);
|
||||
},
|
||||
navigation: function (next) {
|
||||
var navigation = require('../src/navigation/admin');
|
||||
var data = require('../install/data/navigation.json');
|
||||
|
||||
navigation.save(data, next);
|
||||
}
|
||||
}, function (err, results) {
|
||||
if (err) {
|
||||
|
||||
177
test/files/503.html
Normal file
177
test/files/503.html
Normal file
@@ -0,0 +1,177 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Excessive Load Warning</title>
|
||||
<link href='https://fonts.googleapis.com/css?family=Ubuntu:400,500,700' rel='stylesheet' type='text/css'>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: #00A9EA;
|
||||
color: white;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
text-align: center;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-moz-transform-style: preserve-3d;
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 250px;
|
||||
color: #fff;
|
||||
opacity: 0.5;
|
||||
margin: 10px;
|
||||
cursor: pointer;
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
p strong {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
h1 {
|
||||
font-size: 125px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
p strong {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
-webkit-transform: translateY(50%);
|
||||
-ms-transform: translateY(50%);
|
||||
transform: translateY(50%);
|
||||
}
|
||||
|
||||
@-webkit-keyframes bounce {
|
||||
0%, 20%, 53%, 80%, 100% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
40%, 43% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -30px, 0);
|
||||
transform: translate3d(0, -30px, 0);
|
||||
}
|
||||
|
||||
70% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -15px, 0);
|
||||
transform: translate3d(0, -15px, 0);
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: translate3d(0,-4px,0);
|
||||
transform: translate3d(0,-4px,0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%, 20%, 53%, 80%, 100% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
40%, 43% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -30px, 0);
|
||||
transform: translate3d(0, -30px, 0);
|
||||
}
|
||||
|
||||
70% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -15px, 0);
|
||||
transform: translate3d(0, -15px, 0);
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: translate3d(0,-4px,0);
|
||||
transform: translate3d(0,-4px,0);
|
||||
}
|
||||
}
|
||||
|
||||
.bounce {
|
||||
-webkit-animation-name: bounce;
|
||||
animation-name: bounce;
|
||||
-webkit-transform-origin: center bottom;
|
||||
-ms-transform-origin: center bottom;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
|
||||
.animated {
|
||||
-webkit-animation-duration: 1s;
|
||||
animation-duration: 1s;
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animated.infinite {
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.animated.hinge {
|
||||
-webkit-animation-duration: 2s;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
var count = 0,
|
||||
bounce = document.getElementById('click-me');
|
||||
bounce.onclick = function() {
|
||||
count++;
|
||||
bounce.className = '';
|
||||
setTimeout(function() {
|
||||
bounce.className = 'animated bounce';
|
||||
}, 50);
|
||||
|
||||
if (count > 5) {
|
||||
document.getElementById('hide').className = '';
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="center">
|
||||
<h1 id="click-me" class="animated bounce">503</h1>
|
||||
<p>
|
||||
<strong>This forum is temporarily unavailable due to excessive load.</strong>
|
||||
</p>
|
||||
<p>
|
||||
We shouldn't be down for long. Please check back shortly. Sorry for the inconvenience!
|
||||
</p>
|
||||
<p>
|
||||
<small id="hide" class="hide">Alright. You can stop clicking... it's not going to make the site come back sooner!</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
test/files/favicon.ico
Normal file
BIN
test/files/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
test/files/test.png
Normal file
BIN
test/files/test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
@@ -707,8 +707,8 @@ describe('Groups', function () {
|
||||
describe('groups cover', function () {
|
||||
var socketGroups = require('../src/socket.io/groups');
|
||||
var regularUid;
|
||||
var logoPath = path.join(__dirname, '../public/logo.png');
|
||||
var imagePath = path.join(__dirname, '../public/groupcover.png');
|
||||
var logoPath = path.join(__dirname, '../test/files/test.png');
|
||||
var imagePath = path.join(__dirname, '../test/files/groupcover.png');
|
||||
before(function (done) {
|
||||
User.create({username: 'regularuser', password: '123456'}, function (err, uid) {
|
||||
assert.ifError(err);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
--reporter dot
|
||||
--timeout 15000
|
||||
--timeout 25000
|
||||
|
||||
@@ -67,18 +67,18 @@ describe('Upload Controllers', function () {
|
||||
});
|
||||
|
||||
it('should upload a profile picture', function (done) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/user/regular/uploadpicture', path.join(__dirname, '../public/logo.png'), {}, jar, csrf_token, function (err, res, body) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/user/regular/uploadpicture', path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, function (err, res, body) {
|
||||
assert.ifError(err);
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert(Array.isArray(body));
|
||||
assert.equal(body.length, 1);
|
||||
assert.equal(body[0].url, '/assets/uploads/profile/' + regularUid + '-profileimg.png');
|
||||
assert.equal(body[0].url, '/assets/uploads/profile/' + regularUid + '-profileavatar.png');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should upload an image to a post', function (done) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../public/logo.png'), {cid: cid}, jar, csrf_token, function (err, res, body) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../test/files/test.png'), {cid: cid}, jar, csrf_token, function (err, res, body) {
|
||||
assert.ifError(err);
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert(Array.isArray(body));
|
||||
@@ -91,7 +91,7 @@ describe('Upload Controllers', function () {
|
||||
|
||||
it('should upload a file to a post', function (done) {
|
||||
meta.config.allowFileUploads = 1;
|
||||
helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../public/503.html'), {cid: cid}, jar, csrf_token, function (err, res, body) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../test/files/503.html'), {cid: cid}, jar, csrf_token, function (err, res, body) {
|
||||
assert.ifError(err);
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert(Array.isArray(body));
|
||||
@@ -118,7 +118,7 @@ describe('Upload Controllers', function () {
|
||||
});
|
||||
|
||||
it('should upload site logo', function (done) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/uploadlogo', path.join(__dirname, '../public/logo.png'), {}, jar, csrf_token, function (err, res, body) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/uploadlogo', path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, function (err, res, body) {
|
||||
assert.ifError(err);
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert(Array.isArray(body));
|
||||
@@ -128,7 +128,7 @@ describe('Upload Controllers', function () {
|
||||
});
|
||||
|
||||
it('should upload category image', function (done) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/category/uploadpicture', path.join(__dirname, '../public/logo.png'), {params: JSON.stringify({cid: cid})}, jar, csrf_token, function (err, res, body) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/category/uploadpicture', path.join(__dirname, '../test/files/test.png'), {params: JSON.stringify({cid: cid})}, jar, csrf_token, function (err, res, body) {
|
||||
assert.ifError(err);
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert(Array.isArray(body));
|
||||
@@ -138,7 +138,7 @@ describe('Upload Controllers', function () {
|
||||
});
|
||||
|
||||
it('should upload favicon', function (done) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/uploadfavicon', path.join(__dirname, '../public/favicon.ico'), {}, jar, csrf_token, function (err, res, body) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/uploadfavicon', path.join(__dirname, '../test/files/favicon.ico'), {}, jar, csrf_token, function (err, res, body) {
|
||||
assert.ifError(err);
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert(Array.isArray(body));
|
||||
@@ -148,7 +148,7 @@ describe('Upload Controllers', function () {
|
||||
});
|
||||
|
||||
it('should upload touch icon', function (done) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/uploadTouchIcon', path.join(__dirname, '../public/logo.png'), {}, jar, csrf_token, function (err, res, body) {
|
||||
helpers.uploadFile(nconf.get('url') + '/api/admin/uploadTouchIcon', path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, function (err, res, body) {
|
||||
assert.ifError(err);
|
||||
assert.equal(res.statusCode, 200);
|
||||
assert(Array.isArray(body));
|
||||
|
||||
267
test/user.js
267
test/user.js
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user