mirror of
				https://github.com/LibreTranslate/LibreTranslate.git
				synced 2025-10-31 02:27:11 -04:00 
			
		
		
		
	Improvement to under attack mode
This commit is contained in:
		
							parent
							
								
									fd0119bf70
								
							
						
					
					
						commit
						411b50178e
					
				| @ -365,7 +365,11 @@ def create_app(args): | ||||
|                       need_key = True | ||||
| 
 | ||||
|                   if args.under_attack and key_missing: | ||||
|                     need_key = True | ||||
|                     abort(make_response(jsonify({ | ||||
|                         'translatedText': secret.get_emoji(), | ||||
|                         'alternatives': [], | ||||
|                         'detectedLanguage': { 'confidence': 100, 'language': 'en' } | ||||
|                       }), 200)) | ||||
| 
 | ||||
|                   if need_key: | ||||
|                     description = _("Please contact the server operator to get an API key") | ||||
| @ -473,7 +477,8 @@ def create_app(args): | ||||
|             url_prefix=args.url_prefix, | ||||
|             get_api_key_link=args.get_api_key_link, | ||||
|             api_secret=api_secret, | ||||
|             bogus_api_secret=bogus_api_secret), content_type='application/javascript; charset=utf-8') | ||||
|             bogus_api_secret=bogus_api_secret, | ||||
|             under_attack=args.under_attack), content_type='application/javascript; charset=utf-8') | ||||
| 
 | ||||
|       if args.require_api_key_secret: | ||||
|         response.headers['Last-Modified'] = http_date(datetime.now()) | ||||
|  | ||||
| @ -457,6 +457,10 @@ code[class*="language-"], pre[class*="language-"] { | ||||
|   background-color: var(--sec-bg-color) | ||||
| } | ||||
| 
 | ||||
| textarea:disabled{ | ||||
|   opacity: 0.5; | ||||
| } | ||||
| 
 | ||||
| @media (min-width: 280px) { | ||||
|   .btn-text { | ||||
|     display: inline; | ||||
|  | ||||
| @ -60,7 +60,7 @@ class MemoryStorage(Storage): | ||||
|     def set_str(self, key, value, ex=None): | ||||
|         self.store[key] = { | ||||
|             'value': value, | ||||
|             'ex': time.time() + ex | ||||
|             'ex': None if ex is None else time.time() + ex | ||||
|         } | ||||
| 
 | ||||
|     def get_str(self, key): | ||||
|  | ||||
| @ -17,6 +17,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|             settings: {}, | ||||
|             sourceLang: "", | ||||
|             targetLang: "", | ||||
|             apiKey: localStorage.getItem("api_key") || "", | ||||
| 
 | ||||
|             loadingTranslation: false, | ||||
|             inputText: "", | ||||
| @ -45,6 +46,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|         }, | ||||
|         mounted: function() { | ||||
|             const self = this; | ||||
|             window._vueApp = self; | ||||
|             self.$el.classList.add("loaded"); | ||||
| 
 | ||||
|             const settingsRequest = new XMLHttpRequest(); | ||||
| @ -137,7 +139,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|                     '		target: ' + this.$options.filters.escape(this.targetLang) + ',', | ||||
|                     '		format: "' + (this.isHtml ? "html" : "text") + '",', | ||||
|                     '		alternatives: 3,', | ||||
|                     '		api_key: "' + (localStorage.getItem("api_key") || "") + '"', | ||||
|                     '		api_key: "' + this.apiKey + '"', | ||||
|                     '	}),', | ||||
|                     '	headers: { "Content-Type": "application/json" }', | ||||
|                     '});', | ||||
| @ -164,6 +166,9 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|                     }); | ||||
|                     return tgtLangs; | ||||
|                 } | ||||
|             }, | ||||
|             disableInput: function(){ | ||||
|                 return {% if under_attack %}true{% else %}false{% endif %} && this.apiKey === ""; | ||||
|             } | ||||
|         }, | ||||
|         filters: { | ||||
| @ -211,6 +216,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|                 history.pushState(null, '', newRelativePathQuery); | ||||
|             }, | ||||
|             handleInput: function(e){ | ||||
|                 if (this.disableInput) return; | ||||
|                 this.closeSuggestTranslation(e) | ||||
| 
 | ||||
|                 this.updateQueryParam('source', this.sourceLang) | ||||
| @ -245,7 +251,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|                     data.append("target", self.targetLang); | ||||
|                     data.append("format", self.isHtml ? "html" : "text"); | ||||
|                     data.append("alternatives", 3); | ||||
|                     data.append("api_key", localStorage.getItem("api_key") || ""); | ||||
|                     data.append("api_key", self.apiKey); | ||||
|                     if (self.apiSecret) data.append("secret", atob(self.apiSecret)); | ||||
| 
 | ||||
|                     request.open('POST', BaseUrl + '/translate', true); | ||||
| @ -329,7 +335,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|                 data.append("s", self.translatedText); | ||||
|                 data.append("source", self.sourceLang); | ||||
|                 data.append("target", self.targetLang); | ||||
|                 data.append("api_key", localStorage.getItem("api_key") || ""); | ||||
|                 data.append("api_key", self.apiKey); | ||||
| 
 | ||||
|                 request.open('POST', BaseUrl + '/suggest', true); | ||||
|                 request.onload = function() { | ||||
| @ -382,6 +388,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|             }, | ||||
|             translateFile: function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 if (this.disableInput) return; | ||||
| 
 | ||||
|                 let self = this; | ||||
|                 let translateFileRequest = new XMLHttpRequest(); | ||||
| @ -392,7 +399,7 @@ document.addEventListener('DOMContentLoaded', function(){ | ||||
|                 data.append("file", this.inputFile); | ||||
|                 data.append("source", this.sourceLang); | ||||
|                 data.append("target", this.targetLang); | ||||
|                 data.append("api_key", localStorage.getItem("api_key") || ""); | ||||
|                 data.append("api_key", this.apiKey); | ||||
|                 if (self.apiSecret) data.append("secret", self.apiSecret); | ||||
| 
 | ||||
|                 this.loadingFileTranslation = true | ||||
| @ -537,6 +544,9 @@ function setApiKey(){ | ||||
|     if (newKey === null) newKey = ""; | ||||
| 
 | ||||
|     localStorage.setItem("api_key", newKey); | ||||
|     if (window._vueApp){ | ||||
|         window._vueApp.apiKey = newKey; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Color scheme handling | ||||
|  | ||||
| @ -181,11 +181,11 @@ | ||||
| 					{% endif %} | ||||
| 					<h3 class="header center">{{ _h("Translation API") }}</h3> | ||||
| 					<div id="translation-type-btns" class="s12 center" v-if="filesTranslation === true"> | ||||
| 						<button type="button" class="btn btn-switch-type" @click="switchType('text')" :class="{'active': translationType === 'text'}"> | ||||
| 						<button type="button" class="btn btn-switch-type" @click="switchType('text')" :class="{'active': translationType === 'text'}" :disabled="disableInput"> | ||||
| 							<i aria-hidden="true" class="material-icons">title</i> | ||||
| 							<span class="btn-text">{{ _h("Translate Text") }}</span> | ||||
| 						</button> | ||||
| 						<button type="button" class="btn btn-switch-type" @click="switchType('files')" :class="{'active': translationType === 'files'}"> | ||||
| 						<button type="button" class="btn btn-switch-type" @click="switchType('files')" :class="{'active': translationType === 'files'}" :disabled="disableInput"> | ||||
| 							<i aria-hidden="true" class="material-icons">description</i> | ||||
| 							<span class="btn-text">{{ _h("Translate Files") }}</span> | ||||
| 						</button> | ||||
| @ -220,7 +220,7 @@ | ||||
| 								<label for="textarea1" class="sr-only"> | ||||
| 									{{ _h("Text to translate") }} | ||||
| 								</label> | ||||
| 								<textarea id="textarea1" :maxLength="charactersLimit" v-model="inputText" @input="handleInput" ref="inputTextarea" dir="auto"></textarea> | ||||
| 								<textarea id="textarea1" :maxLength="charactersLimit" v-model="inputText" @input="handleInput" ref="inputTextarea" dir="auto" :disabled="disableInput"></textarea> | ||||
| 								<button class="btn-delete-text" title="{{ _h('Delete text') }}" aria-label="{{ _h('Delete text') }}" @click="deleteText"> | ||||
| 									<i class="material-icons">close</i> | ||||
| 								</button> | ||||
| @ -232,7 +232,7 @@ | ||||
| 								<label for="textarea2" class="sr-only"> | ||||
| 									{{ _h("Translated text") }} | ||||
| 								</label> | ||||
| 								<textarea id="textarea2" v-model="translatedText" ref="translatedTextarea" dir="auto" v-bind:readonly="suggestions && !isSuggesting"></textarea> | ||||
| 								<textarea id="textarea2" v-model="translatedText" ref="translatedTextarea" dir="auto" v-bind:readonly="suggestions && !isSuggesting" :disabled="disableInput"></textarea> | ||||
| 									<div class="actions"> | ||||
| 										<button v-if="suggestions && !loadingTranslation && inputText.length && !isSuggesting" class="btn-action" @click="suggestTranslation" aria-label="{{ _h('Suggest translation') }}"> | ||||
| 											<i class="material-icons">edit</i> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user