diff --git a/.api-version b/.api-version index 4122521804..73a86b1970 100644 --- a/.api-version +++ b/.api-version @@ -1 +1 @@ -7.0.0 \ No newline at end of file +7.0.1 \ No newline at end of file diff --git a/antora.yml b/antora.yml index b509a00fa5..df496b588f 100644 --- a/antora.yml +++ b/antora.yml @@ -16,6 +16,12 @@ asciidoc: webcomponent_url: https://cdn.jsdelivr.net/npm/@tinymce/tinymce-webcomponent@2/dist/tinymce-webcomponent.min.js jquery_url: https://cdn.jsdelivr.net/npm/@tinymce/tinymce-jquery@2/dist/tinymce-jquery.min.js default_meta_keywords: tinymce, documentation, docs, plugins, customizable skins, configuration, examples, html, php, java, javascript, image editor, inline editor, distraction-free editor, classic editor, wysiwyg + # product docker variables + dockerimageimportfromwordexporttoword: registry.containers.tiny.cloud/docx-converter-tiny + dockerimageexporttopdf: registry.containers.tiny.cloud/pdf-converter-tiny + dockerimageexporttopdfwindows: registry.containers.tiny.cloud/pdf-converter-windows-tiny + # document converter placeholder variables + exportpdf_service_url: exportpdf_service_url placeholder # product variables productname: TinyMCE productmajorversion: 7 diff --git a/modules/ROOT/nav.adoc b/modules/ROOT/nav.adoc index 241e281c7f..3000691b9c 100644 --- a/modules/ROOT/nav.adoc +++ b/modules/ROOT/nav.adoc @@ -136,6 +136,8 @@ **** Individually licensed plugin services ***** xref:individual-hyperlinking-container.adoc[Hyperlinking service] ***** xref:individual-spelling-container.adoc[Spelling service] +***** xref:individual-export-to-pdf-on-premises.adoc[Export to PDF] +***** xref:individual-import-from-word-and-export-to-word-on-premises.adoc[Import from Word and Export to Word] *** Configure the server-side components **** xref:configure-required-services.adoc[Required configuration] **** xref:configure-common-settings-services.adoc[Optional common settings] diff --git a/modules/ROOT/pages/apis/tinymce.editor.adoc b/modules/ROOT/pages/apis/tinymce.editor.adoc index f5a4852c8b..f07065caf5 100644 --- a/modules/ROOT/pages/apis/tinymce.editor.adoc +++ b/modules/ROOT/pages/apis/tinymce.editor.adoc @@ -83,11 +83,12 @@ manipulation functions.|`xref:apis/tinymce.editor.adoc[Editor]` that could leak memory. This method will be called automatically when the page is unloaded but you can also call it directly if you know what you are doing.|`xref:apis/tinymce.editor.adoc[Editor]` |xref:#dispatch[dispatch()]|Dispatches the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` + +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#execCommand[execCommand()]|Executes a registered command on the current instance. A list of available commands can be found in the tinymce command identifiers documentation.|`xref:apis/tinymce.editor.adoc[Editor]` |xref:#fire[fire()]|Fires the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. __Deprecated in TinyMCE 6.0 and has been marked for removal in TinyMCE 7.0. Use `dispatch` instead.__|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#focus[focus()]|Focuses/activates the editor. This will set this editor as the activeEditor in the tinymce collection it will also place DOM focus inside the editor.|`xref:apis/tinymce.editor.adoc[Editor]` @@ -121,11 +122,11 @@ so all events etc that method has will get dispatched as well.|`xref:apis/tinymc |xref:#nodeChanged[nodeChanged()]|Dispatches out a onNodeChange event to all observers. This method should be called when you need to update the UI states or element path etc.|`xref:apis/tinymce.editor.adoc[Editor]` |xref:#off[off()]|Unbinds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#on[on()]|Binds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#once[once()]|Bind the event callback and once it fires the callback is removed. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#queryCommandState[queryCommandState()]|Returns a command specific state, for example if bold is enabled or not.|`xref:apis/tinymce.editor.adoc[Editor]` |xref:#queryCommandSupported[queryCommandSupported()]|Returns true/false if the command is supported or not.|`xref:apis/tinymce.editor.adoc[Editor]` |xref:#queryCommandValue[queryCommandValue()]|Returns a command specific value, for example the current font size.|`xref:apis/tinymce.editor.adoc[Editor]` @@ -336,7 +337,7 @@ but you can also call it directly if you know what you are doing. dispatch(name: String, args: Object?, bubble: Boolean?): Object ---- Dispatches the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Examples [source, javascript] @@ -385,7 +386,7 @@ the tinymce command identifiers documentation. fire(name: String, args: Object?, bubble: Boolean?): Object ---- Fires the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. __Deprecated in TinyMCE 6.0 and has been marked for removal in TinyMCE 7.0. Use `dispatch` instead.__ ==== Examples @@ -751,7 +752,7 @@ need to update the UI states or element path etc. off(name: String?, callback: Function?): Object ---- Unbinds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Examples [source, javascript] @@ -784,7 +785,7 @@ instance.off(); on(name: String, callback: Function, prepend: Boolean): Object ---- Binds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Examples [source, javascript] @@ -813,7 +814,7 @@ instance.on('event', (e) => { once(name: String, callback: Function): Object ---- Bind the event callback and once it fires the callback is removed. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Parameters diff --git a/modules/ROOT/pages/apis/tinymce.editor.ui.registry.adoc b/modules/ROOT/pages/apis/tinymce.editor.ui.registry.adoc index 44025a5f98..f4250cedc0 100644 --- a/modules/ROOT/pages/apis/tinymce.editor.ui.registry.adoc +++ b/modules/ROOT/pages/apis/tinymce.editor.ui.registry.adoc @@ -42,7 +42,7 @@ UI Components - Context Menu].|`xref:apis/tinymce.editor.ui.registry.adoc[Regist |xref:#addContextToolbar[addContextToolbar()]|Registers a new context toolbar that only appears when a content predicate is matched for example the cursor is on an image element. For information on creating context toolbars, see: -link:https://www.tiny.cloud/docs/tinymce/6/contexttoolbar/[ +link:https://www.tiny.cloud/docs/tinymce/7/contexttoolbar/[ UI Components - Context Toolbar].|`xref:apis/tinymce.editor.ui.registry.adoc[Registry]` |xref:#addGroupToolbarButton[addGroupToolbarButton()]|Registers a new group toolbar button for the toolbar. Renders a toolbar button that opens a floating toolbar when clicked. @@ -201,7 +201,7 @@ addContextToolbar(name: String, obj: Toolbar.ContextToolbarSpec) Registers a new context toolbar that only appears when a content predicate is matched for example the cursor is on an image element. For information on creating context toolbars, see: -link:https://www.tiny.cloud/docs/tinymce/6/contexttoolbar/[ +link:https://www.tiny.cloud/docs/tinymce/7/contexttoolbar/[ UI Components - Context Toolbar]. ==== Parameters diff --git a/modules/ROOT/pages/apis/tinymce.notificationmanager.adoc b/modules/ROOT/pages/apis/tinymce.notificationmanager.adoc index ecc9dbd46c..ffba33ce3a 100644 --- a/modules/ROOT/pages/apis/tinymce.notificationmanager.adoc +++ b/modules/ROOT/pages/apis/tinymce.notificationmanager.adoc @@ -69,6 +69,6 @@ Opens a new notification. * `args (Object)` - A `name: value` collection containing settings such as: `timeout`, `type`, and message (`text`). -For information on the available settings, see: link:https://www.tiny.cloud/docs/tinymce/6/creating-custom-notifications/[Create custom notifications]. +For information on the available settings, see: link:https://www.tiny.cloud/docs/tinymce/7/creating-custom-notifications/[Create custom notifications]. ''' diff --git a/modules/ROOT/pages/apis/tinymce.root.adoc b/modules/ROOT/pages/apis/tinymce.root.adoc index 7a72048596..4c9b577c4b 100644 --- a/modules/ROOT/pages/apis/tinymce.root.adoc +++ b/modules/ROOT/pages/apis/tinymce.root.adoc @@ -52,7 +52,7 @@ Checks if the input object `obj` has the property `prop`.|`xref:apis/tinymce.roo |xref:#inArray[inArray()]|Returns an index of the item or -1 if item is not present in the array.|`xref:apis/tinymce.root.adoc[tinymce]` |xref:#init[init()]|Initializes a set of editors. This method will create editors based on various settings. -For information on basic usage of `init`, see: link:https://www.tiny.cloud/docs/tinymce/6/basic-setup/[Basic setup].|`xref:apis/tinymce.root.adoc[tinymce]` +For information on basic usage of `init`, see: link:https://www.tiny.cloud/docs/tinymce/7/basic-setup/[Basic setup].|`xref:apis/tinymce.root.adoc[tinymce]` |xref:#is[is()]|Checks if a object is of a specific type for example an array.|`xref:apis/tinymce.root.adoc[tinymce]` |xref:#isArray[isArray()]|Returns true/false if the object is an array or not.|`xref:apis/tinymce.root.adoc[tinymce]` |xref:#makeMap[makeMap()]|Makes a name/object map out of an array with names.|`xref:apis/tinymce.root.adoc[tinymce]` @@ -315,7 +315,7 @@ init(options: Object): Promise ---- Initializes a set of editors. This method will create editors based on various settings. -For information on basic usage of `init`, see: link:https://www.tiny.cloud/docs/tinymce/6/basic-setup/[Basic setup]. +For information on basic usage of `init`, see: link:https://www.tiny.cloud/docs/tinymce/7/basic-setup/[Basic setup]. ==== Examples [source, javascript] diff --git a/modules/ROOT/pages/apis/tinymce.util.observable.adoc b/modules/ROOT/pages/apis/tinymce.util.observable.adoc index 8f0329ccf1..f76909ab65 100644 --- a/modules/ROOT/pages/apis/tinymce.util.observable.adoc +++ b/modules/ROOT/pages/apis/tinymce.util.observable.adoc @@ -15,17 +15,17 @@ This mixin adds event binding logic to classes. Adapts the EventDispatcher class |=== |Name|Summary|Defined by |xref:#dispatch[dispatch()]|Dispatches the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#fire[fire()]|Fires the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. __Deprecated in TinyMCE 6.0 and has been marked for removal in TinyMCE 7.0. Use `dispatch` instead.__|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#hasEventListeners[hasEventListeners()]|Returns true/false if the object has a event of the specified name.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#off[off()]|Unbinds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#on[on()]|Binds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |xref:#once[once()]|Bind the event callback and once it fires the callback is removed. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event.|`xref:apis/tinymce.util.observable.adoc[Observable]` |=== [[methods]] @@ -38,7 +38,7 @@ link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more det dispatch(name: String, args: Object?, bubble: Boolean?): Object ---- Dispatches the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Examples [source, javascript] @@ -65,7 +65,7 @@ instance.dispatch('event', {...}); fire(name: String, args: Object?, bubble: Boolean?): Object ---- Fires the specified event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. __Deprecated in TinyMCE 6.0 and has been marked for removal in TinyMCE 7.0. Use `dispatch` instead.__ ==== Examples @@ -111,7 +111,7 @@ Returns true/false if the object has a event of the specified name. off(name: String?, callback: Function?): Object ---- Unbinds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Examples [source, javascript] @@ -144,7 +144,7 @@ instance.off(); on(name: String, callback: Function, prepend: Boolean): Object ---- Binds an event listener to a specific event by name. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Examples [source, javascript] @@ -173,7 +173,7 @@ instance.on('event', (e) => { once(name: String, callback: Function): Object ---- Bind the event callback and once it fires the callback is removed. Consult the -link:https://www.tiny.cloud/docs/tinymce/6/events/[event reference] for more details on each event. +link:https://www.tiny.cloud/docs/tinymce/7/events/[event reference] for more details on each event. ==== Parameters diff --git a/modules/ROOT/pages/apis/tinymce.windowmanager.adoc b/modules/ROOT/pages/apis/tinymce.windowmanager.adoc index cebcb7f4d0..2686c2605f 100644 --- a/modules/ROOT/pages/apis/tinymce.windowmanager.adoc +++ b/modules/ROOT/pages/apis/tinymce.windowmanager.adoc @@ -119,8 +119,8 @@ Opens a new window. ==== Parameters -* `config (Object)` - For information on the available options, see: link:https://www.tiny.cloud/docs/tinymce/6/dialog-configuration/#options[Dialog - Configuration options]. -* `params (Object)` - (Optional) For information on the available options, see: link:https://www.tiny.cloud/docs/tinymce/6/dialog-configuration/#configuration-parameters[Dialog - Configuration parameters]. +* `config (Object)` - For information on the available options, see: link:https://www.tiny.cloud/docs/tinymce/7/dialog-configuration/#options[Dialog - Configuration options]. +* `params (Object)` - (Optional) For information on the available options, see: link:https://www.tiny.cloud/docs/tinymce/7/dialog-configuration/#configuration-parameters[Dialog - Configuration parameters]. ==== Return value @@ -138,7 +138,7 @@ Opens a new window for the specified url. ==== Parameters -* `config (Object)` - For information on the available options, see: link:https://www.tiny.cloud/docs/tinymce/6/urldialog/#configuration[URL dialog - Configuration]. +* `config (Object)` - For information on the available options, see: link:https://www.tiny.cloud/docs/tinymce/7/urldialog/#configuration[URL dialog - Configuration]. ==== Return value diff --git a/modules/ROOT/pages/individual-export-to-pdf-on-premises.adoc b/modules/ROOT/pages/individual-export-to-pdf-on-premises.adoc new file mode 100644 index 0000000000..40f8f4f3d1 --- /dev/null +++ b/modules/ROOT/pages/individual-export-to-pdf-on-premises.adoc @@ -0,0 +1,21 @@ += Deploy the {productname} {pluginname} service server-side component using Docker (individually licensed) +:navtitle: Export to PDF +:description: Setting up Export to PDF using Docker. +:keywords: server-side, docker, export-to-pdf, on-premises +:pluginname: Export to PDF + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-overview.adoc[] + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-requirements.adoc[] + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-installation.adoc[] + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-fonts.adoc[] + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-autorization.adoc[] + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-api-usage.adoc[] + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-ssl-communication.adoc[] + +include::partial$individually-licensed-components/export-to-pdf/export-to-pdf-logs.adoc[] \ No newline at end of file diff --git a/modules/ROOT/pages/individual-import-from-word-and-export-to-word-on-premises.adoc b/modules/ROOT/pages/individual-import-from-word-and-export-to-word-on-premises.adoc new file mode 100644 index 0000000000..3cca7d5e1b --- /dev/null +++ b/modules/ROOT/pages/individual-import-from-word-and-export-to-word-on-premises.adoc @@ -0,0 +1,19 @@ += Deploy the {productname} {pluginname} service server-side component using Docker (individually licensed) +:navtitle: Import from Word and Export to Word +:description: Setting up Import from Word and Export to Word using Docker. +:keywords: server-side, docker, import-from-word, export-to-word, on-premises +:pluginname: Import from Word and Export to Word + +include::partial$individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-overview-on-premises.adoc[] + +include::partial$individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-requirements-on-premises.adoc[] + +include::partial$individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-installation-on-premises.adoc[] + +include::partial$individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-autorization-on-premises.adoc[] + +include::partial$individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-api-usage-on-premises.adoc[] + +include::partial$individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-ssl-communication-on-premises.adoc[] + +include::partial$individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-logs-on-premises.adoc[] \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-api-usage.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-api-usage.adoc new file mode 100644 index 0000000000..6f7b93f9e4 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-api-usage.adoc @@ -0,0 +1,42 @@ +[[api-usage]] +== API Usage + +The {pluginname} On-Premises converter provides the ability to convert an HTML document to a PDF file via Restful API. + +The API is available on `+http://localhost:[port]+` (by default the `port` is `8080`). + +[NOTE] +The REST API documentation is available at `+http://localhost:[port]/docs+`. +Alternatively, refer to the specifications in link:https://exportpdf.converter.tiny.cloud/docs[https://exportpdf.converter.tiny.cloud/docs^]. + +If the authorization for the API is enabled, provided an authorization token. More instructions can be found in the xref:individual-export-to-pdf-on-premises.adoc#authorization[authorization] section. + +=== Using additional HTTP headers + +If fetching some resources (e.g. images) used in a generated PDF requires passing an additional authorization factor in the form of additional HTTP headers: + +. It can be defined on the application startup by setting `EXTRA_HTTP_HEADERS` environmental variable where the value is a stringified JSON object with required headers. +. It can be defined in a request sent to the PDF Converter API in `options`: + +[source, js, subs="attributes+"] +---- +const data = { + html: '

I am a teapot

', + css: 'p { color: red; }', + options: { + extra_http_headers: { + authorization: 'Bearer ' + } + } +}; + +axios.post( '{exportpdf_service_url}', data, config ) + .then( response => { + fs.writeFileSync('./file.pdf', response.data, 'binary') + }).catch( error => { + console.log( error ); + }); +---- + +[TIP] +Headers defined in the application config and from the request are merged. If the same header is defined in both places, a header value from PDF options is prioritized over the value from the application config. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-autorization.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-autorization.adoc new file mode 100644 index 0000000000..6bcf161084 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-autorization.adoc @@ -0,0 +1,97 @@ +[[authorization]] +== Authorization + +To enable authorization, set the `SECRET_KEY` environment variable during the xref:individual-export-to-pdf-on-premises.adoc#installation[installation]. + +If the `SECRET_KEY` variable is set, then all requests must have a header with a JWT (JSON Web Token) signed with this key. The token should be passed as a value of the `Authorization` header for each request sent to the {pluginname} REST API. + +[NOTE] +If the `SECRET_KEY` is not setup during the installation, then {pluginname} On-Premises will not require any headers with tokens when sending requests to the {pluginname} REST API. However, this it is not recommend to skip the authorization when running {pluginname} On-Premises in a public network. + +=== Generating the token + +{companyname} recommends using the libraries listed on link:http://jwt.io/[jwt.io] to generate the token. The token is considered valid, when: + +* it is signed with the same `SECRET_KEY` as passed to the {pluginname} On-Premises instance, +* it was created within the last 24 hours, +* it is not issued in the future (e.i. the iat timestamp cannot be newer than the current time), +* it has not expired yet. + + +If the specific use case involves sending requests from a backend server, then JWT tokens can be generated locally, as shown in the below request example. + +In the case of editor plugins or other frontend usages, a token endpoint should be created, that returns a valid JWT token for authorized users. + +.Example of a endpoint implementation. +[source, js] +---- +const express = require( 'express' ); +const jwt = require( 'jsonwebtoken' ); + +const SECRET_KEY = 'secret_key'; + +const app = express(); + +app.use( ( req, res, next ) => { + res.setHeader( 'Access-Control-Allow-Origin', '*' ); + res.setHeader( 'Access-Control-Allow-Methods', 'GET' ); + + next(); +}); + +app.get( '/', ( req, res ) => { + const result = jwt.sign( {}, SECRET_KEY, { algorithm: 'HS256' } ); + + res.send( result ); +}); + +app.listen( 8080, () => console.log( 'Listening on port 8080' ) ); +---- + +=== Using editor plugins + +Plugins for {productname} will automatically request the token from the given `tokenUrl` variable and set the `Authorization` header when making an export request. + +[NOTE] +Refer to the xref:exportpdf.adoc[{pluginname}] plugin documentation for details on adding the {pluginname} feature to the editor. + +=== Request example with an Authorization header + +The following example presents a request that generates valid JWT token and sets it as `Authorization` header: + +[source, js] +---- +const fs = require( 'fs' ); +const jwt = require( 'jsonwebtoken' ); +const axios = require( 'axios' ); + +const SECRET_KEY = 'secret'; + +const token = jwt.sign( {}, SECRET_KEY, { algorithm: 'HS256' } ); + +const data = { + html: "

I am a teapot

", + css: "p { color: red; }", +}; + +const config = { + headers: { + 'Authorization': token + }, + responseType: 'arraybuffer', +}; + +axios.post( 'http://localhost:8080/v1/convert', data, config ) + .then( response => { + fs.writeFileSync('./file.pdf', response.data, 'binary'); + }).catch( error => { + console.log( error ); + }); +---- + +`SECRET_KEY` it’s the key which has been passed to the {pluginname} On-Premises instance + +Please refer to the link:https://exportpdf.converter.tiny.cloud/docs[{pluginname} REST API documentation] to start using the service. + +[NOTE] +If API clients like Postman or Insomnia are used, then set the JWT token as an `Authorization` header in the `Headers` tab. Do not use the built-in token authorization as this will generate invalid header with a `Bearer` prefix added to the token. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-fonts.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-fonts.adoc new file mode 100644 index 0000000000..f950c20157 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-fonts.adoc @@ -0,0 +1,65 @@ +[[fonts]] +== Fonts + +During document writing, the possibility of using many different fonts can be very important to users. + +Using the appropriate font can change the appearance of the document and emphasize its style. + +{pluginname} Converter allows link:https://exportpdf.converter.tiny.cloud/docs#section/Web-Fonts[Web Fonts^] to be used, which provided the integrator with the ability to use standard operating system fonts or use custom fonts without the need to import them using CSS. + +Below is a list of the basic fonts included in the image: + +[source] +---- +OpenSans-Bold.ttf +OpenSans-BoldItalic.ttf +OpenSans-ExtraBold.ttf +OpenSans-ExtraBoldItalic.ttf +OpenSans-Italic.ttf +OpenSans-Light.ttf +OpenSans-LightItalic.ttf +OpenSans-Regular.ttf +OpenSans-Semibold.ttf +OpenSans-SemiboldItalic.ttf +---- + +However, additional fonts can be added to {pluginname} Converter in two ways: + +* Use Unix-like PDF-Converter image `{dockerimageexporttopdf}` and mount fonts directory to it. +** See xref:individual-export-to-pdf-on-premises.adoc#add-custom-fonts-to-pdf-converter[Add custom fonts to PDF Converter] section. +* Use Windows PDF-Converter image `{dockerimageexporttopdf}` and mount to it fonts directory from the Windows operating system on which the container is running. +** See Use Windows fonts in PDF Converter section. + +[NOTE] +The fonts inside the mounted volume will be installed on the docker image operating system. Only the `.ttf` and `.otf` font formats are supported. If other font formats are used, these will need to be converted to the supported format prior or use fonts such as link:https://exportpdf.converter.tiny.cloud/docs#section/Web-Fonts[Web Fonts^]. + +[TIP] +Ensure that the converted fonts can be installed and used on your local machine first, before installing them on the docker container. + +[[add-custom-fonts-to-pdf-converter]] +=== Add custom fonts to PDF Converter + +If custom fonts are being used in PDF files, use the `pdf-converter-tiny` Docker image and mount the directory with the custom fonts for the PDF Converter application running on a machine with a Unix-like system (this includes Docker on Windows with a WSL backend). + +The `{dockerimageexporttopdf}` Docker image need to be run on a Unix-like operating system and mount the `~/your_fonts_dir:/usr/share/fonts/your_fonts_dir` volume. + +Launch the Docker container on Unix-like operating system example: + +[source, bash, subs="attributes+"] +---- +docker run --init -v ~/your_fonts_dir:/usr/share/fonts/your_fonts_dir -p 8080:8080 -e LICENSE_KEY=[your_license_key] {dockerimageexporttopdf}:[version] +---- + +[[use-windows-fonts-in-pdf-converter]] +=== Use Windows fonts in PDF Converter + +If using Windows fonts like Arial, Verdana, etc. in PDF files, use `pdf-converter-windows-tiny` Docker image that allows you to run the application on a machine with Windows operating system and mount fonts from the system. + +You just need to run `{dockerimageexporttopdf}` Docker image on Windows operating system and mount `C:\Windows\Fonts:C:\Windows\Fonts` volume. + +Launch the Docker container on Windows operating system example: + +[source, bash, subs="attributes+"] +---- +docker run -v C:\Windows\Fonts:C:\Windows\Fonts -p 8080:8080 --env LICENSE_KEY=[your_license_key] {dockerimageexporttopdfwindows}:[version] +---- \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-installation.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-installation.adoc new file mode 100644 index 0000000000..45195b0e28 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-installation.adoc @@ -0,0 +1,98 @@ +[[installation]] +== Installation + +[NOTE] +A valid license key is needed in order to install {pluginname} On-Premises. +link:https://www.tiny.cloud/contact/[Contact us] for a trial license key. + +=== Supported technologies + +The application is provided as a docker image by default. + +It can be run with any Open Container runtime tool e.g. link:https://kubernetes.io/[Kubernetes], link:https://www.redhat.com/en/technologies/cloud-computing/openshift[OpenShift], link:https://podman.io/[Podman], link:https://docs.docker.com/[Docker] and many others. + +Refer to the xref:individual-export-to-pdf-on-premises.adoc#requirements[Requirements guide] for more information about the hardware and software requirements to run the {pluginname} On-Premises. + +=== Setting up the application using a Docker container + +. The username and password credentials supplied by Tiny are utilized for logging into the Docker registry and retrieving the Docker image. +. Containerize the application using `docker` or `docker-compose`. +. Use a demo page to verify if the application works properly. + +==== Containerize example using docker + +Login to Docker registry: + +[source, sh, subs="attributes+"] +---- +docker login -u [username] -p [password] registry.containers.tiny.cloud +---- + +Launch the Docker container: + +[source, sh, subs="attributes+"] +---- +docker run --init -p 8080:8080 -e LICENSE_KEY=[your_license_key] {dockerimageexporttopdf}:[version] +---- + +If using authorization provide the SECRET_KEY: + +[source, sh, subs="attributes+"] +---- +docker run --init -p 8080:8080 -e LICENSE_KEY=[your_license_key] -e SECRET_KEY=[your_secret_key] {dockerimageexporttopdf}:[version] +---- + +Read more about using authorization in the xref:individual-export-to-pdf-on-premises.adoc#authorization[authorization] section. + +==== Containerize example using docker-compose + +. Create the docker-compose.yml file: ++ +[source, yml, subs="attributes+"] +---- +version: "3.8" +services: + pdf-converter-tiny: + image: {dockerimageexporttopdf}:[version] + ports: + - "8080:8080" + restart: always + init: true + environment: + LICENSE_KEY: "license_key" + # Secret Key is optional + SECRET_KEY: "secret_key" + # Custom request origin is optional + CUSTOM_REQUEST_ORIGIN: "https://your_custom_origin" +---- ++ +For details on `SECRET_KEY` usage check the xref:individual-export-to-pdf-on-premises.adoc#authorization[authorization] section. ++ +. Run: + +[source, bash] +---- +docker-compose up +---- + +[NOTE] +==== +* Without a correct `LICENSE_KEY` the application will not start. +** If the license is invalid, a wrong license key error will display in the logs and the application will not run. +* It is advisable to override the SECRET_KEY variable using a unique and hard to guess string for security reasons. +* If the specific infrastructure has strict CORS enabled, then use the `CUSTOM_REQUEST_ORIGIN` variable to set the origin of requests made by the converter. The default value is `https://pdf-internal`. +==== + +=== Windows fonts support + +If using Windows fonts like Calibri, Verdana, etc. in PDF files, use the `pdf-converter-windows-tiny` Docker image and run it on a Windows operating system. + +See xref:individual-export-to-pdf-on-premises.adoc#fonts[Fonts] section for more details. + +=== Next steps + +Use the link:http://localhost:8080/v1/convert[http://localhost:8080/v1/convert] endpoint to export PDF files. Check out the xref:individual-export-to-pdf-on-premises.adoc#authorization[authorization] section to learn more about tokens and token endpoints. + +Use the demo page available on link:http://localhost:8080/demo[http://localhost:8080/demo] to generate an example PDF file. + +Refer to the {pluginname} REST API documentation on link:http://localhost:8080/docs[http://localhost:8080/docs] for more details. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-logs.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-logs.adoc new file mode 100644 index 0000000000..6a23a39e6d --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-logs.adoc @@ -0,0 +1,212 @@ +[[logs]] +== Logs + +The logs from {pluginname} On-Premises are written to `stdout` and `stderr`. Most of them are formatted in JSON. They can be used for monitoring or debugging purposes. In production environments, It is recommend storing the logs to files or using a distributed logging system (like ELK or CloudWatch). + +=== Monitoring {pluginname} with logs + +To get more insight into how the {pluginname} On-Premises is performing, logs can be used for monitoring. To enable these, add the `ENABLE_METRIC_LOGS=true` environment variable. + +=== Log structure + +The log structure contains the following information: + +* `handler`: A unified identifier of action. Use this field to identify calls. +* `traceId`: A unique RPC call ID. +* `tags`: A semicolon-separated list of tags. Use this field to filter metrics logs. +* `data`: An object containing additional information. It might vary between different transports. +* `data.duration`: The request duration in milliseconds. +* `data.transport`: The type of the request transport. It could be http or ws (websocket). +* `data.status`: The request status. It can be equal to success, fail, warning. +* `data.statusCode`: The response status in HTTP status code standard. + +Additionally, for the HTTP transport, the following information is included: + +* `data.url`: The URL path. +* `data.method`: The request method. + +In case of an error, `data.status` will be equal to failed and `data.message` will contain the error message. + +An example log for HTTP transport: + +[source] +---- +{ + "level": 30, + "time": "2021-03-09T11:15:09.154Z", + "msg": "Request summary", + "handler": "convertHtmlToPdf", + "traceId": "85f13d92-57df-4b3b-98bb-0ca41a5ae601", + "data": { + "duration": 2470, + "transport": "http", + "statusCode": 200, + "status": "success", + "url": "/v1/convert", + "method": "POST" + }, + "tags": "metrics" +} +---- +// verify if this is something we will add. +//// +See example charts to check how to use logs for monitoring purposes. +//// + +=== Docker + +The docker has built-in logging mechanisms that capture logs from the output of the containers. The default logging driver writes the logs to files. + +When using this driver, use the `docker logs` command to show logs from a container. The `-f` flag can be added to view logs in real time. Refer to the link:https://docs.docker.com/engine/reference/commandline/logs/[official Docker documentation^] for more information about the logs command. + +[NOTE] +When a container is running for a long period of time, the logs can take up a lot of space. To avoid this problem, make sure that the log rotation is enabled. This can be set with the `max-size` option. + +=== Distributed logging + +If running more than one instance of {pluginname} On-Premises, It is recommend using a distributed logging system. It allows for viewing and analyzing logs from all instances in one place. + +==== AWS CloudWatch and other cloud solutions + +If running {pluginname} On-Premises in the cloud, the simplest and recommended way is to use a service that is available at the selected provider. + +Here are some of the available services: + +* AWS: link:https://aws.amazon.com/CloudWatch[CloudWatch^] +* Google Cloud: link:https://cloud.google.com/logging[Cloud Logging^] +* Azure: link:https://azure.microsoft.com/en-us/services/monitor/[Azure Monitor^] + +To use CloudWatch with AWS ECS, a log group must be created before, and the log driver must be changed to `awslogs`. When the log driver is configured properly, logs will be streamed directly to CloudWatch. + +The `logConfiguration` may look similar to this: + +[source, json] +---- +"logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-region": "us-west-2", + "awslogs-group": "tinysource", + "awslogs-stream-prefix": "tiny-pdf-converter-logs" + } +} +---- + +Refer to the link:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html[Using the awslogs Log Driver] article for more information. + +=== On-Premises solutions + +If using a specific infrastructure such as your own or for some reason cannot use the service offered by a provider, some on-premises distributed logging system can be used. + +There are a lot of solutions available, including: + +* link:https://www.elastic.co/what-is/elk-stack[ELK^] + link:https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-getting-started.html[Filebeat^] + +This is a stack built on top of Elasticsearch, Logstash and Kibana. In this configuration, Elasticsearch stores logs, Filebeat reads logs from Docker and sends them to Elasticsearch, and Kibana is used to view them. Logstash is not necessary because logs are already structured. + +* link:https://www.fluentd.org/[Fluentd^] + +It uses a dedicated link:https://docs.docker.com/config/containers/logging/fluentd[Docker log driver^] to send the logs. It has a built-in frontend, but can also be integrated with Elasticsearch and Kibana for better filtering. + +* link:https://www.graylog.org/[Graylog^] + +It uses a dedicated link:https://docs.docker.com/config/containers/logging/gelf[Docker^] log driver to send the logs. It has a built-in frontend and needs Elasticsearch to store the logs as well as a MongoDB database to store the configuration. + +==== Example configuration + +The example configuration uses Fluentd, Elasticsearch, and Kibana to capture logs from Docker. + +Before running {pluginname} On-Premises, prepare the logging services. For the purposes of this example, Docker Compose is used. Create the fluentd, elasticsearch and kibana services inside the docker-compose.yml file: + +[source, yaml] +---- +version: '3.7' +services: + fluentd: + build: ./fluentd + volumes: + - ./fluentd/fluent.conf:/fluentd/etc/fluent.conf + ports: + - "24224:24224" + - "24224:24224/udp" + + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:6.8.5 + expose: + - 9200 + ports: + - "9200:9200" + + kibana: + image: docker.elastic.co/kibana/kibana:6.8.5 + environment: + ELASTICSEARCH_HOSTS: "http://elasticsearch:9200" + ports: + - "5601:5601" +---- + +To integrate Fluentd with Elasticsearch, first install `fluent-plugin-elasticsearch` in the Fluentd image. To do this, create a `fluentd/Dockerfile` with the following content: + +[source, dockerfile] +---- +FROM fluent/fluentd:v1.10-1 + +USER root + +RUN apk add --no-cache --update build-base ruby-dev \ + && gem install fluent-plugin-elasticsearch \ + && gem sources --clear-all +---- + +Next, configure the input server and connection to Elasticsearch in the `fluentd/fluent.conf` file: + +[source, xml] +---- + + @type forward + port 24224 + bind 0.0.0.0 + + + @type copy + + @type elasticsearch + host elasticsearch + port 9200 + logstash_format true + logstash_prefix fluentd + logstash_dateformat %Y%m%d + include_tag_key true + type_name access_log + tag_key @log_name + flush_interval 1s + + + @type stdout + + +---- + +The services are now ready to run: + +[source, bash] +---- +docker-compose up --build +---- + +When the services are ready, start {pluginname} On-Premises. + +[source, bash, subs="attributes+"] +---- +docker run --init -p 8080:8080 \ +--log-driver=fluentd \ +--log-opt fluentd-address=[Fluentd address]:24224 \ +[Your config here] \ +{dockerimageexporttopdf}:[version] +---- + +* Open Kibana in your browser. +** It is available at link:http://localhost:5601/[http://localhost:5601/]. +* During the first run, you may be asked about creating an index. +* Use the `fluentd-*` pattern and press the “Create” button. +* After this step, the logs should appear in the “Discover” tab. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-overview.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-overview.adoc new file mode 100644 index 0000000000..578111b725 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-overview.adoc @@ -0,0 +1,10 @@ +[[overview]] +== Overview + +The On-Premises version of the {pluginname} Converter is an application that can be installed and run on the customer’s in-house servers and computing infrastructure, including a private cloud. It contains all the features of the {pluginname} Converter available as SaaS. + +A valid license key is required in order to install {pluginname} Converter On-Premises. +link:https://www.tiny.cloud/contact/[Contact us] for a trial license key. + + +The only requirement to run {pluginname} On-Premises is a container runtime or orchestration tool e.g. Docker, Kubernetes, Podman. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-requirements.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-requirements.adoc new file mode 100644 index 0000000000..e7dc513c9e --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-requirements.adoc @@ -0,0 +1,23 @@ +[[requirements]] +== Requirements + +To run {pluginname} On-Premises a Docker environment is required. Alternatively, use CaaS available from your cloud provider, like AWS ECS, Google GKE, or Azure ACS. + +There are many factors affecting {pluginname} On-Premises performance. The most influential are the size of exported content, the size of images, and the number of concurrent requests. Also, because your application can prioritize fast response times, or it should handle high load, it is impossible to provide one recommended server specification, that will fit all use cases. + +Assuming response time below 10 seconds, one server (2CPU 2GB RAM) with 1 docker container can handle: + +* up to 40 concurrent requests with an average content of 1 A4 page (~1k characters and 1 image) +* up to 25 concurrent requests with an average content of 5 A4 pages (~7,5k characters and 5 images) +* up to 10 concurrent requests with an average content of 20 A4 pages (~30k characters and 20 images) + +[NOTE] +The above concurrent requests numbers are not a hard limit of {pluginname} On-Premises instance. It can handle more concurrent requests, but the response time will be longer. + +=== High availability + +One docker container with {pluginname} On-Premises benefits from additional CPUs on the machine. To scale your app on a single machine, increase the number of CPUs, however, {companyname} recommends scaling on at least three hosts to ensure the reliability of the system. + +A load balancer, like HAProxy or NGINX (see the load balancer configuration examples in the SSL communication guide), is required for scaling on several machines. Of course, it is possible to use any cloud provider for scaling, like Amazon ECS, Azure Container Instances, or Kubernetes. + +link:https://www.tiny.cloud/contact/[Contact us] if you have any questions about server resources needed for your use case of {pluginname} On-Premises. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-ssl-communication.adoc b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-ssl-communication.adoc new file mode 100644 index 0000000000..193cb88f60 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/export-to-pdf/export-to-pdf-ssl-communication.adoc @@ -0,0 +1,68 @@ +[[ssl-communication]] +== SSL Communication + +Its possible to communicate with {pluginname} On-Premises using secure connections. To achieve this, the load balancer like `NGINX` or `HAProxy` needs to be setup with your SSL certificate. + +`HAProxy` and `NGINX` configuration examples below. + +=== HAProxy example + +Here is a basic `HAProxy` configuration: + +[source, nginx] +---- +global + daemon + maxconn 256 + tune.ssl.default-dh-param 2048 + +defaults + mode http + timeout connect 5000ms + timeout client 50000ms + timeout server 50000ms + +frontend http-in + bind *:80 + bind *:443 ssl crt /etc/ssl/your_certificate.pem + http-request set-header X-Forwarded-Proto https if { ssl_fc } + http-request set-header X-Forwarded-Proto http if !{ ssl_fc } + redirect scheme https if !{ ssl_fc } + + default_backend servers + +backend servers + server server1 127.0.0.1:8000 maxconn 32 +---- + +=== NGINX example + +Here is a basic `NGINX` configuration: + +[source, nginx] +---- +events { + worker_connections 1024; +} + +http { + server { + server_name your.domain.name; + + listen 443; + ssl on; + ssl_certificate /etc/ssl/your_cert.crt; + ssl_certificate_key /etc/ssl/your_cert_key.key; + + location / { + proxy_pass http://127.0.0.1:8000; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + } + } +} +---- \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-api-usage-on-premises.adoc b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-api-usage-on-premises.adoc new file mode 100644 index 0000000000..8b5081a61a --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-api-usage-on-premises.adoc @@ -0,0 +1,15 @@ +[[api-usage]] +== API usage + +{pluginname} On-Premises consists of two services: + +* xref:exportword.adoc[Export to Word] provides conversion from an HTML document to a `.docx` file via Restful API. +* xref:importword.adoc[Import from Word] allows importing `.docx` file and converting it into a styled HTML document with comments and suggestions attached. + +The API is available on `+http://localhost:[port]+` (by default the port is 8080). + +[NOTE] +The REST API documentation is available at `+http://localhost:[port]/docs+`. +Alternatively you can check specification in our public resources for link:https://importdocx.converter.tiny.cloud/docs#section/Import-from-Word[Import from Word^] and the link:https://exportdocx.converter.tiny.cloud/docs#section/Export-to-Word[Export to Word^] plugins. + +If you have the authorization for the API enabled, you should provide an authorization token. More instructions you can find in the authorization section. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-autorization-on-premises.adoc b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-autorization-on-premises.adoc new file mode 100644 index 0000000000..c36301f913 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-autorization-on-premises.adoc @@ -0,0 +1,69 @@ +[[authorization]] +== Authorization + +To enable authorization, set the `SECRET_KEY` environment variable during the xref:individual-import-from-word-and-export-to-word-on-premises.adoc#installation[installation]. + +If the `SECRET_KEY` variable is set, then all requests must have a header with a JWT (JSON Web Token) signed with this key. The token should be passed as a value of the `Authorization` header for each request sent to the {pluginname} REST API. + +[NOTE] +If the `SECRET_KEY` is not setup during the installation, then {pluginname} On-Premises will not require any headers with tokens when sending requests to the {pluginname} REST API. However, this it is not recommend to skip the authorization when running {pluginname} On-Premises in a public network. + +=== Generating the token + +{companyname} recommends using the libraries listed on link:http://jwt.io/[jwt.io] to generate the token. The token is considered valid, when: + +* it is signed with the same `SECRET_KEY` as passed to the {pluginname} On-Premises instance, +* it was created within the last 24 hours, +* it is not issued in the future (e.i. the `iat` timestamp cannot be newer than the current time), +* it has not expired yet. + +Tokens for the {pluginname} On-Premises do not require any additional claims such as the environment ID (which is specific for Collaboration Server On-Premises), the token can be created with an empty payload. + +If the specific use case involves sending requests from a backend server, then JWT tokens can be generated locally, as shown in the below request example. + +In the case of editor plugins or other frontend usages, a token endpoint should be created, that returns a valid JWT token for authorized users. + +=== Using editor plugins + +The are are two plugins available for {productname}: the xref:importword.adoc[Import from Word] and the xref:exportword.adoc[Export to Word] plugins. The plugins will automatically request the token from the given `tokenUrl` variable and will set the `Authorization` header when making an export request. Refer to the respective guides for details on adding the {pluginname} features to your WYSIWYG editor! + +=== Request example with an Authorization header + +The following example presents a request that generates a valid JWT token and sets it as an `Authorization` header: + +[source, js] +---- +const fs = require( 'fs' ); +const jwt = require( 'jsonwebtoken' ); +const axios = require( 'axios' ); + +const SECRET_KEY = 'secret'; + +const token = jwt.sign( {}, SECRET_KEY, { algorithm: 'HS256' } ); + +const data = { + html: "

I am a teapot

", + css: "p { color: red; }", +}; + +const config = { + headers: { + Authorization: token + }, + responseType: 'arraybuffer', +}; + +axios.post( 'http://localhost:8080/v1/convert', data, config ) + .then( response => { + fs.writeFileSync('./file.docx', response.data, 'binary'); + } ).catch( error => { + console.log( error ); + } ); +---- + +`SECRET_KEY`: This is the key what has been passed to the {pluginname} On-Premises instance. + +Please refer to the link:https://importdocx.converter.tiny.cloud/docs#section/Import-from-Word[Import from Word^] and the link:https://exportdocx.converter.tiny.cloud/docs#section/Export-to-Word[Export to Word^] REST API documentation to start using the service. + +[NOTE] +If API clients like Postman or Insomnia are used, then set the JWT token as an `Authorization` header in the `Headers` tab. Do not use the built-in token authorization as this will generate invalid header with a `Bearer` prefix added to the token. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-installation-on-premises.adoc b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-installation-on-premises.adoc new file mode 100644 index 0000000000..3694110b64 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-installation-on-premises.adoc @@ -0,0 +1,89 @@ +[[installation]] +== Installation + +[NOTE] +A valid license key is needed in order to install {pluginname} On-Premises. +link:https://www.tiny.cloud/contact/[Contact us] for a trial license key. + +=== Supported technologies + +The application is provided as a docker image by default. + +It can be run with any Open Container runtime tool e.g. link:https://kubernetes.io/[Kubernetes], link:https://www.redhat.com/en/technologies/cloud-computing/openshift[OpenShift], link:https://podman.io/[Podman], link:https://docs.docker.com/[Docker] and many others. + +Refer to the xref:individual-import-from-word-and-export-to-word-on-premises.adoc#requirements[Requirements guide] for more information about the hardware and software requirements to run the {pluginname} On-Premises. + +=== Setting up the application using a Docker container + +. The username and password credentials supplied by Tiny are utilized for logging into the Docker registry and retrieving the Docker image. +. Containerize the application using `docker` or `docker-compose`. +. Use a demo page to verify if the application works properly. + +==== Containerize example using docker + +Login to Docker registry: + +[source, sh, subs="attributes+"] +---- +docker login -u [username] -p [password] registry.containers.tiny.cloud +---- + +Launch the Docker container: + +[source, sh, subs="attributes+"] +---- +docker run --init -p 8080:8080 -e LICENSE_KEY=[your_license_key] {dockerimageimportfromwordexporttoword}:[version] +---- + +If using authorization provide the SECRET_KEY: + +[source, sh, subs="attributes+"] +---- +docker run --init -p 8080:8080 -e LICENSE_KEY=[your_license_key] -e SECRET_KEY=[your_secret_key] {dockerimageimportfromwordexporttoword}:[version] +---- + +Read more about using authorization in the xref:individual-import-from-word-and-export-to-word-on-premises.adoc#authorization[authorization] section. + +==== Containerize example using docker-compose + +. Create the docker-compose.yml file: ++ +[source, yml, subs="attributes+"] +---- +version: "3.8" +services: + doc-converter: + image: {dockerimageimportfromwordexporttoword}:[version] + ports: + - "8080:8080" + restart: always + init: true + environment: + LICENSE_KEY: "licensekey" + # Secret Key is optional + SECRET_KEY: "secret_key" +---- ++ +For details on `SECRET_KEY` usage check the xref:individual-import-from-word-and-export-to-word-on-premises.adoc#authorization[authorization] section. ++ +. Run: + +[source, bash] +---- +docker-compose up +---- + +[NOTE] +==== +* Without a correct `LICENSE_KEY` the application will not start. +** If the license is invalid, a wrong license key error will display in the logs and the application will not run. +* It is advisable to override the `SECRET_KEY` variable using a unique and hard to guess string for security reasons. +==== + +=== Next steps + +Use the link:http://localhost:8080/v1/convert[http://localhost:8080/v1/convert] endpoint to export DOCX files. Check out the xref:individual-import-from-word-and-export-to-word-on-premises.adoc#authorization[authorization] section to learn more about tokens and token endpoints. + +Use the demo page available on link:http://localhost:8080/demo[http://localhost:8080/demo] to generate an example DOCX file. + +Refer to the {pluginname} REST API documentation on link:http://localhost:8080/docs[http://localhost:8080/docs] for more details. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-logs-on-premises.adoc b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-logs-on-premises.adoc new file mode 100644 index 0000000000..29ff606fee --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-logs-on-premises.adoc @@ -0,0 +1,208 @@ +[[logs]] +== Logs + +The logs from {pluginname} On-Premises are written to `stdout` and `stderr`. Most of them are formatted in JSON. They can be used for monitoring or debugging purposes. In production environments, It is recommend storing the logs to files or using a distributed logging system (like ELK or CloudWatch). + +=== Monitoring {pluginname} with logs + +To get more insight into how the {pluginname} On-Premises is performing, logs can be used for monitoring. To enable these, add the `ENABLE_METRIC_LOGS=true` environment variable. + +=== Log structure + +The log structure contains the following information: + +* `handler`: A unified identifier of action. Use this field to identify calls. +* `traceId`: A unique RPC call ID. +* `tags`: A semicolon-separated list of tags. Use this field to filter metrics logs. +* `data`: An object containing additional information. It might vary between different transports. +* `data.duration`: The request duration in milliseconds. +* `data.transport`: The type of the request transport. It could be http or ws (websocket). +* `data.status`: The request status. It can be equal to success, fail, warning. +* `data.statusCode`: The response status in HTTP status code standard. + +Additionally, for the HTTP transport, the following information is included: + +* `data.url`: The URL path. +* `data.method`: The request method. + +In case of an error, `data.status` will be equal to `failed` and `data.message` will contain the error message. + +An example log for HTTP transport: + +[source] +---- +{ + "level": 30, + "time": "2021-03-09T11:15:09.154Z", + "msg": "Request summary", + "handler": "postConvert", + "traceId": "85f13d92-57df-4b3b-98bb-0ca41a5ae601", + "data": { + "duration": 752, + "transport": "http", + "statusCode": 200, + "status": "success", + "url": "/v1/convert", + "method": "POST" + }, + "tags": "metrics" +} +---- + +=== Docker + +The docker has built-in logging mechanisms that capture logs from the output of the containers. The default logging driver writes the logs to files. + +When using this driver, use the `docker logs` command to show logs from a container. Use the `-f` flag to view logs in real time. Refer to the link:https://docs.docker.com/engine/reference/commandline/logs/[official Docker documentation] for more information about the logs command. + +[NOTE] +When a container is running for a long period of time, the logs can take up a lot of space. To avoid this problem, you should make sure that the log rotation is enabled. This can be set with the `max-size` option. + +=== Distributed logging + +If running more than one instance of {pluginname} On-Premises, It is recommend using a distributed logging system. It allows for viewing and analyzing logs from all instances in one place. + +=== AWS CloudWatch and other cloud solutions + +If running {pluginname} On-Premises in the cloud, the simplest and recommended way is to use a service that is available at the selected provider. + +Here are some of the available services: + +* AWS: link:https://aws.amazon.com/CloudWatch[CloudWatch^] +* Google Cloud: link:https://cloud.google.com/logging[Cloud Logging^] +* Azure: link:https://azure.microsoft.com/en-us/services/monitor/[Azure Monitor^] + +To use CloudWatch with AWS ECS, a log group must be created before, and the log driver must be changed to `awslogs`. When the log driver is configured properly, logs will be streamed directly to CloudWatch. + +The `logConfiguration` may look similar to this: + +[source, json] +---- +"logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-region": "us-west-2", + "awslogs-group": "tinysource", + "awslogs-stream-prefix": "tiny-docx-converter-logs" + } +} +---- + +Refer to the link:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_awslogs.html[Using the awslogs Log Driver] article for more information. + +=== On-Premises solutions + +If using a specific infrastructure such as your own or for some reason cannot use the service offered by a provider, some on-premises distributed logging system can be used. + +There are a lot of solutions available, including: + +* link:https://www.elastic.co/what-is/elk-stack[ELK^] + link:https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-getting-started.html[Filebeat^] + +This is a stack built on top of Elasticsearch, Logstash and Kibana. In this configuration, Elasticsearch stores logs, Filebeat reads logs from Docker and sends them to Elasticsearch, and Kibana is used to view them. Logstash is not necessary because logs are already structured. + +* link:https://www.fluentd.org/[Fluentd^] + +It uses a dedicated link:https://docs.docker.com/config/containers/logging/fluentd[Docker log driver^] to send the logs. It has a built-in frontend, but can also be integrated with Elasticsearch and Kibana for better filtering. + +* link:https://www.graylog.org/[Graylog^] + +It uses a dedicated link:https://docs.docker.com/config/containers/logging/gelf[Docker^] log driver to send the logs. It has a built-in frontend and needs Elasticsearch to store the logs as well as a MongoDB database to store the configuration. + +==== Example configuration + +The example configuration uses Fluentd, Elasticsearch and Kibana to capture logs from Docker. + +Before running {pluginname} On-Premises, prepare the logging services. For the purposes of this example, Docker Compose is used. Create the `fluentd`, `elasticsearch` and `kibana` services inside the `docker-compose.yml` file: + +[source, yaml] +---- +version: '3.7' +services: + fluentd: + build: ./fluentd + volumes: + - ./fluentd/fluent.conf:/fluentd/etc/fluent.conf + ports: + - "24224:24224" + - "24224:24224/udp" + + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:6.8.5 + expose: + - 9200 + ports: + - "9200:9200" + + kibana: + image: docker.elastic.co/kibana/kibana:6.8.5 + environment: + ELASTICSEARCH_HOSTS: "http://elasticsearch:9200" + ports: + - "5601:5601" +---- + +To integrate Fluentd with Elasticsearch, you first need to install `fluent-plugin-elasticsearch` in the Fluentd image. To do this, create a `fluentd/Dockerfile` with the following content: + +[source, dockerfile] +---- +FROM fluent/fluentd:v1.10-1 + +USER root + +RUN apk add --no-cache --update build-base ruby-dev \ + && gem install fluent-plugin-elasticsearch \ + && gem sources --clear-all +---- + +Next, configure the input server and connection to Elasticsearch in the `fluentd/fluent.conf` file: + +[source, xml] +---- + + @type forward + port 24224 + bind 0.0.0.0 + + + @type copy + + @type elasticsearch + host elasticsearch + port 9200 + logstash_format true + logstash_prefix fluentd + logstash_dateformat %Y%m%d + include_tag_key true + type_name access_log + tag_key @log_name + flush_interval 1s + + + @type stdout + + +---- + +The services are now ready to run: + +[source, bash] +---- +docker-compose up --build +---- + +When the services are ready, start the {pluginname} On-Premises. + +[source, bash, subs="attributes+"] +---- +docker run --init -p 8080:8080 \ +--log-driver=fluentd \ +--log-opt fluentd-address=[Fluentd address]:24224 \ +[Your config here] \ +{dockerimageimportfromwordexporttoword}:[version] +---- + +* Open Kibana in your browser. +** It is available at link:http://localhost:5601/[http://localhost:5601/]. +* During the first run, you may be asked about creating an index. +* Use the `fluentd-*` pattern and press the “Create” button. +* After this step, the logs should appear in the “Discover” tab. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-overview-on-premises.adoc b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-overview-on-premises.adoc new file mode 100644 index 0000000000..c6f59f086d --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-overview-on-premises.adoc @@ -0,0 +1,10 @@ +[[overview]] +== Overview + +{pluginname} is a set of two converter services that allow for both exporting a structured HTML content (e.g. created with {productname} WYSIWYG editor) into a `.docx` Microsoft Word file and for importing content from `.docx` and `.dotx` files and converting it into a styled HTML document. + +A valid license key is needed in order to install {pluginname} On-Premises. link:https://www.tiny.cloud/contact/[Contact us] for a trial license key. + +The documentation in this section refers to a simplified version of the {pluginname} On-Premises which was designed to be easy to set up and maintain (while preserving all the features). It also lowers the running costs by reducing the number of servers required to run the whole application to the minimum. + +The only requirement to run {pluginname} On-Premises is a container runtime or orchestration tool e.g. Docker, Kubernetes, Podman. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-requirements-on-premises.adoc b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-requirements-on-premises.adoc new file mode 100644 index 0000000000..b315d08898 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-requirements-on-premises.adoc @@ -0,0 +1,23 @@ +[[requirements]] +== Requirements + +To run {pluginname} On-Premises, a Docker environment is required. Alternatively, use a CaaS available from your cloud provider, such as AWS ECS, Google GKE or Azure ACS. + +There are many factors that may affect Export to Word On-Premises performance. The most influential are: the size of exported content, the size of images, and the number of concurrent requests. Also, because your application can prioritize fast response times, or it should handle high load, it is impossible to provide one recommended server specification, that will fit all use cases. + +Assuming response time below 10 seconds, one server (2CPU 2GB RAM) with 1 docker container can handle: + +* up to 45 concurrent requests with an average content of 1 A4 page (~1k characters) +* up to 30 concurrent requests with an average content of 5 A4 pages (~7,5k characters) +* up to 10 concurrent requests with an average content of 20 A4 pages (~30k characters) + +[NOTE] +The listed concurrent requests numbers are not a hard limit of a {pluginname} On-Premises instance. It can handle more concurrent requests, but the response time will be longer. + +=== High availability + +One docker container with {pluginname} On-Premises benefits from additional CPUs on the machine. It is recommended that 2 CPUs are allocated for every docker container. To scale your app on a single machine, increase the number of CPUs and docker containers, however, {productname} recommends scaling on at least three hosts to ensure the reliability of the system. + +A load balancer, like HAProxy or NGINX (see the load balancer configuration examples in the SSL communication guide), is required for scaling on several machines. Of course, it is possible to use any cloud provider for scaling, like Amazon ECS, Azure Container Instances or Kubernetes. + +link:https://www.tiny.cloud/contact/[Contact us] if you have any questions about server resources needed for your use case of {pluginname} On-Premises. \ No newline at end of file diff --git a/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-ssl-communication-on-premises.adoc b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-ssl-communication-on-premises.adoc new file mode 100644 index 0000000000..83c159e7f6 --- /dev/null +++ b/modules/ROOT/partials/individually-licensed-components/import-from-word-and-export-to-word/import-from-word-and-export-to-word-ssl-communication-on-premises.adoc @@ -0,0 +1,68 @@ +[[sll-communication]] +== SSL Communication + +Its possible to communicate with {pluginname} On-Premises using secure connections. To achieve this, the load balancer like `NGINX` or `HAProxy` needs to be setup with your SSL certificate. + +`HAProxy` and `NGINX` configuration examples below. + +=== HAProxy example + +Here is a basic `HAProxy` configuration: + +[source, nginx] +---- +global + daemon + maxconn 256 + tune.ssl.default-dh-param 2048 + +defaults + mode http + timeout connect 5000ms + timeout client 50000ms + timeout server 50000ms + +frontend http-in + bind *:80 + bind *:443 ssl crt /etc/ssl/your_certificate.pem + http-request set-header X-Forwarded-Proto https if { ssl_fc } + http-request set-header X-Forwarded-Proto http if !{ ssl_fc } + redirect scheme https if !{ ssl_fc } + + default_backend servers + +backend servers + server server1 127.0.0.1:8000 maxconn 32 +---- + +=== NGINX example + +Here is a basic NGINX configuration: + +[source, nginx] +---- +events { + worker_connections 1024; +} + +http { + server { + server_name your.domain.name; + + listen 443; + ssl on; + ssl_certificate /etc/ssl/your_cert.crt; + ssl_certificate_key /etc/ssl/your_cert_key.key; + + location / { + proxy_pass http://127.0.0.1:8000; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + } + } +} +---- \ No newline at end of file