This commit is contained in:
LoekJanssen 2016-08-20 18:54:16 +00:00 committed by GitHub
commit 425c3298d6
7 changed files with 165 additions and 23 deletions

View File

@ -0,0 +1,20 @@
Language = {
connectedUnencrypted: 'Verbunden mit (unverschlüsselt)',
connectedEncrypted: 'Verbunden mit (verschlüsselt)',
errorHostPort: 'Richten Sie Host und Port ein',
ready: 'NoVNC bereit: Native WebSockets',
readyEmulation: 'NoVNC bereit: Emulierte WebSockets',
authentication: 'Authentifizierung',
errorFatal: 'Schwerwiegender Fehler. Die Verbindung kann nicht hergestellt werden.',
errorTimeout: 'Timeout. Verbindung unterbrochen',
errorConnected: 'Fehler beim Verbinden',
errorInitializing: 'Fehler beim Initialisieren',
startingVNC: 'Starte VNC Authentifizierung',
errorDisconnected: 'Verbindung zum Server getrennt',
errorConnection: 'Verbindung zum Server konnte nicht hergestellt werden',
errorProtocolVerion: 'Unvollständige Protokollversion',
errorServerVersion: 'Ungültige Serverversion',
errorSecurity: 'Sicherheitsfehler',
errorAuthFailure: 'Authentifizierungsfehler',
errorAuthAttempts: 'Zu viele Authentifizierungsversuche'
};

View File

@ -0,0 +1,20 @@
Language = {
connectedUnencrypted: 'Connected to (unencrypted)',
connectedEncrypted: 'Connected to (encrypted)',
errorHostPort: 'Must set host and port',
ready: 'noVNC ready: native WebSockets',
readyEmulation: 'noVNC ready: WebSockets emulation',
authentication: 'Authentication',
errorFatal: 'Fatal error, cannot continue',
errorTimeout: 'Disconnect timeout',
errorConnected: 'Error while connected',
errorInitializing: 'Error while initializing',
startingVNC: 'Starting VNC handshake',
errorDisconnected: 'Server disconnected',
errorConnection: 'Failed to connect to server',
errorProtocolVerion: 'Incomplete protocol version',
errorServerVersion: 'Invalid server version',
errorSecurity: 'Security failure',
errorAuthFailure: 'Authentication failure',
errorAuthAttempts: 'Too many authentication attempts'
};

View File

@ -0,0 +1,20 @@
Language = {
connectedUnencrypted: 'Verbonden met (onversleuteld)',
connectedEncrypted: 'Verbonden met (versleuteld)',
errorHostPort: 'Stel host en poort in',
ready: 'NoVNC gereed: geïntegreerde WebSockets',
readyEmulation: 'NoVNC gereed: geëmuleerde WebSocktets',
authentication: 'Authenticatie',
errorFatal: 'Onherstelbare fout',
errorTimeout: 'Timeout tijdens verbreken van verbinding',
errorConnected: 'Fout tijdens verbinding',
errorInitializing: 'Fout tijdens initializatie',
startingVNC: 'Starten van VNC handshake',
errorDisconnected: 'Verbindng met server verbroken',
errorConnection: 'Kon geen verbinding met de server maken',
errorProtocolVerion: 'Protocol versie is incompleet',
errorServerVersion: 'Ongeldige server versie',
errorSecurity: 'Beveiligingsfout',
errorAuthFailure: 'Authenticatie fout',
errorAuthAttempts: 'Te veel Authenticatie pogingen'
};

View File

@ -184,7 +184,7 @@ var RFB;
this._sock.on('message', this._handle_message.bind(this)); this._sock.on('message', this._handle_message.bind(this));
this._sock.on('open', function () { this._sock.on('open', function () {
if (this._rfb_state === 'connect') { if (this._rfb_state === 'connect') {
this._updateState('ProtocolVersion', "Starting VNC handshake"); this._updateState('ProtocolVersion', Util.Localisation.get('startingVNC'));
} else { } else {
this._fail("Got unexpected WebSocket connection"); this._fail("Got unexpected WebSocket connection");
} }
@ -202,11 +202,11 @@ var RFB;
if (this._rfb_state === 'disconnect') { if (this._rfb_state === 'disconnect') {
this._updateState('disconnected', 'VNC disconnected' + msg); this._updateState('disconnected', 'VNC disconnected' + msg);
} else if (this._rfb_state === 'ProtocolVersion') { } else if (this._rfb_state === 'ProtocolVersion') {
this._fail('Failed to connect to server' + msg); this._fail(Util.Localisation.get('errorConnection') + msg);
} else if (this._rfb_state in {'failed': 1, 'disconnected': 1}) { } else if (this._rfb_state in {'failed': 1, 'disconnected': 1}) {
Util.Error("Received onclose while disconnected" + msg); Util.Error("Received onclose while disconnected" + msg);
} else { } else {
this._fail("Server disconnected" + msg); this._fail(Util.Localisation.get('errorDisconnected') + msg);
} }
this._sock.off('close'); this._sock.off('close');
}.bind(this)); }.bind(this));
@ -219,7 +219,7 @@ var RFB;
var rmode = this._display.get_render_mode(); var rmode = this._display.get_render_mode();
if (Websock_native) { if (Websock_native) {
Util.Info("Using native WebSockets"); Util.Info("Using native WebSockets");
this._updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode); this._updateState('loaded', Util.Localisation.get('ready')+', ' + rmode);
} else { } else {
this._cleanupSocket('fatal'); this._cleanupSocket('fatal');
throw new Error("WebSocket support is required to use noVNC"); throw new Error("WebSocket support is required to use noVNC");
@ -237,7 +237,7 @@ var RFB;
this._rfb_path = (path !== undefined) ? path : ""; this._rfb_path = (path !== undefined) ? path : "";
if (!this._rfb_host || !this._rfb_port) { if (!this._rfb_host || !this._rfb_port) {
return this._fail("Must set host and port"); return this._fail(Util.Localisation.get('errorHostPort'));
} }
this._updateState('connect'); this._updateState('connect');
@ -252,7 +252,7 @@ var RFB;
sendPassword: function (passwd) { sendPassword: function (passwd) {
this._rfb_password = passwd; this._rfb_password = passwd;
this._rfb_state = 'Authentication'; this._rfb_state = Util.Localisation.get('authentication');
setTimeout(this._init_msg.bind(this), 1); setTimeout(this._init_msg.bind(this), 1);
}, },
@ -487,7 +487,7 @@ var RFB;
case 'disconnect': case 'disconnect':
this._disconnTimer = setTimeout(function () { this._disconnTimer = setTimeout(function () {
this._fail("Disconnect timeout"); this._fail(Util.Localisation.get('errorTimeout'));
}.bind(this), this._disconnectTimeout * 1000); }.bind(this), this._disconnectTimeout * 1000);
this._print_stats(); this._print_stats();
@ -499,9 +499,9 @@ var RFB;
if (oldstate === 'disconnected') { if (oldstate === 'disconnected') {
Util.Error("Invalid transition from 'disconnected' to 'failed'"); Util.Error("Invalid transition from 'disconnected' to 'failed'");
} else if (oldstate === 'normal') { } else if (oldstate === 'normal') {
Util.Error("Error while connected."); Util.Error(Util.Localisation.get('errorConnected'));
} else if (oldstate === 'init') { } else if (oldstate === 'init') {
Util.Error("Error while initializing."); Util.Error(Util.Localisation.get('errorInitializing'));
} }
// Make sure we transition to disconnected // Make sure we transition to disconnected
@ -628,7 +628,7 @@ var RFB;
_negotiate_protocol_version: function () { _negotiate_protocol_version: function () {
if (this._sock.rQlen() < 12) { if (this._sock.rQlen() < 12) {
return this._fail("Incomplete protocol version"); return this._fail(Util.Localisation.get('errorProtocolVerion'));
} }
var sversion = this._sock.rQshiftStr(12).substr(4, 7); var sversion = this._sock.rQshiftStr(12).substr(4, 7);
@ -652,7 +652,7 @@ var RFB;
this._rfb_version = 3.8; this._rfb_version = 3.8;
break; break;
default: default:
return this._fail("Invalid server version " + sversion); return this._fail(Util.Localisation.get('errorServerVerion') + ' ' + sversion);
} }
if (is_repeater) { if (is_repeater) {
@ -687,7 +687,7 @@ var RFB;
if (num_types === 0) { if (num_types === 0) {
var strlen = this._sock.rQshift32(); var strlen = this._sock.rQshift32();
var reason = this._sock.rQshiftStr(strlen); var reason = this._sock.rQshiftStr(strlen);
return this._fail("Security failure: " + reason); return this._fail(Util.Localisation.get('errorSecurity') + ': ' + reason);
} }
this._rfb_auth_scheme = 0; this._rfb_auth_scheme = 0;
@ -838,7 +838,7 @@ var RFB;
if (this._sock.rQwait("auth reason", 4)) { return false; } if (this._sock.rQwait("auth reason", 4)) { return false; }
var strlen = this._sock.rQshift32(); var strlen = this._sock.rQshift32();
var reason = this._sock.rQshiftStr(strlen); var reason = this._sock.rQshiftStr(strlen);
return this._fail("Auth failure: " + reason); return this._fail(Util.Localisation.get('errorAuthFailure') + ': ' + reason);
case 1: // no auth case 1: // no auth
if (this._rfb_version >= 3.8) { if (this._rfb_version >= 3.8) {
@ -875,11 +875,11 @@ var RFB;
var reason = this._sock.rQshiftStr(length); var reason = this._sock.rQshiftStr(length);
return this._fail(reason); return this._fail(reason);
} else { } else {
return this._fail("Authentication failure"); return this._fail(Util.Localisation.get('errorAuthFailure'));
} }
return false; return false;
case 2: case 2:
return this._fail("Too many auth attempts"); return this._fail(Util.Localisation.get('errorAuthAttempts'));
} }
}, },
@ -993,9 +993,9 @@ var RFB;
this._sock.flush(); this._sock.flush();
if (this._encrypt) { if (this._encrypt) {
this._updateState('normal', 'Connected (encrypted) to: ' + this._fb_name); this._updateState('normal', Util.Localisation.get('connectedEncrypted') + ': ' + this._fb_name);
} else { } else {
this._updateState('normal', 'Connected (unencrypted) to: ' + this._fb_name); this._updateState('normal', Util.Localisation.get('connectedUnencrypted') + ': ' + this._fb_name);
} }
}, },
@ -2145,4 +2145,4 @@ var RFB;
Util.Error("Server sent compress level pseudo-encoding"); Util.Error("Server sent compress level pseudo-encoding");
} }
}; };
})(); })();

View File

@ -17,7 +17,8 @@ var UI;
// Load supporting scripts // Load supporting scripts
window.onscriptsload = function () { UI.load(); }; window.onscriptsload = function () { UI.load(); };
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js", Util.load_scripts([Util.Localisation.getLanguageFileLocation(),
"webutil.js", "base64.js", "websock.js", "des.js",
"keysymdef.js", "keyboard.js", "input.js", "display.js", "keysymdef.js", "keyboard.js", "input.js", "display.js",
"rfb.js", "keysym.js", "inflator.js"]); "rfb.js", "keysym.js", "inflator.js"]);

View File

@ -11,6 +11,7 @@
// Globals defined here // Globals defined here
var Util = {}; var Util = {};
var Language = {};
/* /*
@ -620,3 +621,83 @@ Util.Flash = (function () {
version = v.match(/\d+/g); version = v.match(/\d+/g);
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
}()); }());
Util.Localisation = {
defaultLanguage: 'en-GB',
/*
* Not all languages have been translated
* Some countries prefer a certain language
*/
supportedLanguages: {
'en': 'en-GB',
'en-GB': 'en-GB',
'en-US': 'en-GB',
'nl': 'nl-NL',
'nl-NL': 'nl-NL',
'nl-BE': 'nl-NL',
'de': 'de-DE',
'de-DE': 'de-DE'
},
// Get language file location
getLanguageFileLocation: function () {
return 'locale/locale-'+Util.Localisation.getLanguageCode()+'.js';
},
// Get language code from browser and verify it
getLanguageCode: function () {
var languageCode = Util.Localisation.getUserPreferredLanguage();
for (var index = 0; index < languageCode.length; index++) {
var supportedLanguageCode = Util.Localisation.getSupportedLanguageCode(languageCode[index]);
if (supportedLanguageCode) {
return supportedLanguageCode;
}
}
return Util.Localisation.defaultLanguage;
},
/*
* Retrieve user preferred languages
* Navigator.languages only available in Chrome (32+) and FireFox (32+)
* Fall back to navigator.language for other browsers
*/
getUserPreferredLanguage: function () {
if (typeof window.navigator.languages == 'object') {
return window.navigator.languages;
} else {
var userLang = navigator.language || navigator.userLanguage;
return [userLang];
}
},
/*
* Verify if languagecode is supported
* Return the languagecode of the language to use or null if not available
*/
getSupportedLanguageCode: function (languageCode) {
var supportedLanguages = Util.Localisation.supportedLanguages;
for (var key in supportedLanguages) {
if (supportedLanguages.hasOwnProperty(key)) {
if (key === languageCode) {
// Return the supported language or good alternative
return supportedLanguages[key];
}
}
}
// LanguageCode not supported
return null;
},
// Retrieve localised text
get: function (id) {
if (Language[id]) {
return Language[id];
} else {
return '{'+id+'}';
}
}
};

View File

@ -107,10 +107,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
beforeEach(function () { this.clock = sinon.useFakeTimers(); }); beforeEach(function () { this.clock = sinon.useFakeTimers(); });
afterEach(function () { this.clock.restore(); }); afterEach(function () { this.clock.restore(); });
it('should set the state to "Authentication"', function () { it('should set the state to "{authentication}"', function () {
client._rfb_state = "blah"; client._rfb_state = "blah";
client.sendPassword('pass'); client.sendPassword('pass');
expect(client._rfb_state).to.equal('Authentication'); expect(client._rfb_state).to.equal('{authentication}');
}); });
it('should call init_msg "soon"', function () { it('should call init_msg "soon"', function () {
@ -637,7 +637,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
client._sock._websocket._receive_data(failure_data); client._sock._websocket._receive_data(failure_data);
expect(client._fail).to.have.been.calledTwice; expect(client._fail).to.have.been.calledTwice;
expect(client._fail).to.have.been.calledWith('Security failure: whoops'); expect(client._fail).to.have.been.calledWith('{errorSecurity}: whoops');
}); });
it('should transition to the Authentication state and continue on successful negotiation', function () { it('should transition to the Authentication state and continue on successful negotiation', function () {
@ -677,7 +677,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
sinon.spy(client, '_fail'); sinon.spy(client, '_fail');
client._sock._websocket._receive_data(new Uint8Array(data)); client._sock._websocket._receive_data(new Uint8Array(data));
expect(client._rfb_state).to.equal('failed'); expect(client._rfb_state).to.equal('failed');
expect(client._fail).to.have.been.calledWith('Auth failure: Whoopsies'); expect(client._fail).to.have.been.calledWith('{errorAuthFailure}: Whoopsies');
}); });
it('should transition straight to SecurityResult on "no auth" (1) for versions >= 3.8', function () { it('should transition straight to SecurityResult on "no auth" (1) for versions >= 3.8', function () {