diff --git a/roles/authelia-for-wiki_js/defaults/main.json b/roles/authelia-for-wiki_js/defaults/main.json new file mode 100644 index 0000000..f6531bc --- /dev/null +++ b/roles/authelia-for-wiki_js/defaults/main.json @@ -0,0 +1,6 @@ +{ + "var_authelia_for_wiki_js_wiki_js_url_base": "https://wiki-js.example.org", + "var_authelia_for_wiki_js_client_id": "wiki_js", + "var_authelia_for_wiki_js_client_secret": "REPLACE_ME", + "var_authelia_for_wiki_js_strategy_id": "authelia" +} diff --git a/roles/authelia-for-wiki_js/info.md b/roles/authelia-for-wiki_js/info.md new file mode 100644 index 0000000..43e5da8 --- /dev/null +++ b/roles/authelia-for-wiki_js/info.md @@ -0,0 +1,9 @@ +## Beschreibung + +Um [Wiki.js](../wiki.js) gegen [Authelia](../authelia) authentifizieren zu lassen + + +## Verweise + +[Wiki.js-Dokumentation | Authentication](https://docs.requarks.io/auth) +[Authelia-Dokumentation | Wiki.js Integration](https://www.authelia.com/integration/openid-connect/wikijs/) diff --git a/roles/authelia-for-wiki_js/tasks/main.json b/roles/authelia-for-wiki_js/tasks/main.json new file mode 100644 index 0000000..185f052 --- /dev/null +++ b/roles/authelia-for-wiki_js/tasks/main.json @@ -0,0 +1,25 @@ +[ + { + "name": "configuration | emplace", + "become": true, + "ansible.builtin.template": { + "src": "authelia-client-conf.json.j2", + "dest": "/etc/authelia/conf.d/clients/wiki_js.json" + } + }, + { + "name": "configuration | apply", + "become": true, + "ansible.builtin.command": { + "cmd": "/usr/bin/authelia-conf-compose" + } + }, + { + "name": "restart service", + "become": true, + "ansible.builtin.systemd_service": { + "state": "restarted", + "name": "authelia" + } + } +] diff --git a/roles/authelia-for-wiki_js/templates/authelia-client-conf.json.j2 b/roles/authelia-for-wiki_js/templates/authelia-client-conf.json.j2 new file mode 100644 index 0000000..8537aea --- /dev/null +++ b/roles/authelia-for-wiki_js/templates/authelia-client-conf.json.j2 @@ -0,0 +1,17 @@ +{ + "client_id": "{{var_authelia_for_wiki_js_client_id}}", + "client_secret": "{{var_authelia_for_wiki_js_client_secret}}", + "client_name": "Wiki.js", + "public": false, + "authorization_policy": "one_factor", + "redirect_uris": [ + "{{var_authelia_for_wiki_js_wiki_js_url_base}}/login/{{var_authelia_for_wiki_js_strategy_id}}/callback" + ], + "scopes": [ + "openid", + "email", + "profile" + ], + "userinfo_signed_response_alg": "none", + "token_endpoint_auth_method": "client_secret_post" +} diff --git a/roles/postgresql-for-wiki_js/defaults/main.json b/roles/postgresql-for-wiki_js/defaults/main.json new file mode 100644 index 0000000..b227a2e --- /dev/null +++ b/roles/postgresql-for-wiki_js/defaults/main.json @@ -0,0 +1,5 @@ +{ + "var_postgresql_for_wiki_js_username": "wiki_js_user", + "var_postgresql_for_wiki_js_password": "REPLACE_ME", + "var_postgresql_for_wiki_js_schema": "wiki_js" +} diff --git a/roles/postgresql-for-wiki_js/tasks/main.json b/roles/postgresql-for-wiki_js/tasks/main.json new file mode 100644 index 0000000..c8aafea --- /dev/null +++ b/roles/postgresql-for-wiki_js/tasks/main.json @@ -0,0 +1,49 @@ +[ + { + "name": "packages", + "become": true, + "ansible.builtin.apt": { + "update_cache": true, + "pkg": [ + "acl", + "python3-psycopg2" + ] + } + }, + { + "name": "user", + "become": true, + "become_user": "postgres", + "community.postgresql.postgresql_user": { + "state": "present", + "name": "{{var_postgresql_for_wiki_js_username}}", + "password": "{{var_postgresql_for_wiki_js_password}}" + }, + "environment": { + "PGOPTIONS": "-c password_encryption=scram-sha-256" + } + }, + { + "name": "schema", + "become": true, + "become_user": "postgres", + "community.postgresql.postgresql_db": { + "state": "present", + "name": "{{var_postgresql_for_wiki_js_schema}}", + "owner": "{{var_postgresql_for_wiki_js_username}}" + } + }, + { + "name": "rights", + "become": true, + "become_user": "postgres", + "community.postgresql.postgresql_privs": { + "state": "present", + "db": "{{var_postgresql_for_wiki_js_schema}}", + "objs": "ALL_IN_SCHEMA", + "roles": "{{var_postgresql_for_wiki_js_username}}", + "privs": "ALL", + "grant_option": true + } + } +] diff --git a/roles/wiki_js-and-nginx/defaults/main.json b/roles/wiki_js-and-nginx/defaults/main.json new file mode 100644 index 0000000..b1dd624 --- /dev/null +++ b/roles/wiki_js-and-nginx/defaults/main.json @@ -0,0 +1,5 @@ +{ + "var_wiki_js_and_nginx_domain": "wiki-js.example.org", + "var_wiki_js_and_nginx_internal_port": 5632, + "var_wiki_js_and_nginx_tls_mode": "force" +} diff --git a/roles/wiki_js-and-nginx/info.md b/roles/wiki_js-and-nginx/info.md new file mode 100644 index 0000000..3e54803 --- /dev/null +++ b/roles/wiki_js-and-nginx/info.md @@ -0,0 +1,3 @@ +## Verweise + +- [Wiki.js-Dokumentation | Web Server](https://docs.requarks.io/en/install/requirements#web-server) diff --git a/roles/wiki_js-and-nginx/tasks/main.json b/roles/wiki_js-and-nginx/tasks/main.json new file mode 100644 index 0000000..d12f711 --- /dev/null +++ b/roles/wiki_js-and-nginx/tasks/main.json @@ -0,0 +1,35 @@ +[ + { + "name": "deactivate default site", + "become": true, + "ansible.builtin.file": { + "state": "absent", + "dest": "/etc/nginx/sites-enabled/default" + } + }, + { + "name": "emplace configuration | data", + "become": true, + "ansible.builtin.template": { + "src": "conf.j2", + "dest": "/etc/nginx/sites-available/{{var_wiki_js_and_nginx_domain}}" + } + }, + { + "name": "emplace configuration | link", + "become": true, + "ansible.builtin.file": { + "state": "link", + "src": "/etc/nginx/sites-available/{{var_wiki_js_and_nginx_domain}}", + "dest": "/etc/nginx/sites-enabled/{{var_wiki_js_and_nginx_domain}}" + } + }, + { + "name": "restart nginx", + "become": true, + "ansible.builtin.systemd_service": { + "state": "restarted", + "name": "nginx" + } + } +] diff --git a/roles/wiki_js-and-nginx/templates/conf.j2 b/roles/wiki_js-and-nginx/templates/conf.j2 new file mode 100644 index 0000000..186cc05 --- /dev/null +++ b/roles/wiki_js-and-nginx/templates/conf.j2 @@ -0,0 +1,33 @@ +{% macro wiki_js_common() %} + location / { + proxy_pass http://localhost:{{var_wiki_js_and_nginx_internal_port | string}}; + } +{% endmacro %} + +server { + server_name {{var_wiki_js_and_nginx_domain}}; + + listen 80; + listen [::]:80; + +{% if (var_wiki_js_and_nginx_tls_mode == 'force') %} + return 301 https://$http_host$request_uri; +{% else %} +{{ wiki_js_common() }} +{% endif %} +} + +{% if (var_wiki_js_and_nginx_tls_mode != 'disable') %} +server { + server_name {{var_wiki_js_and_nginx_domain}}; + + listen 443 ssl http2; + listen [::]:443 ssl http2; + + ssl_certificate_key /etc/ssl/private/{{var_wiki_js_and_nginx_domain}}.pem; + ssl_certificate /etc/ssl/fullchains/{{var_wiki_js_and_nginx_domain}}.pem; + include /etc/nginx/ssl-hardening.conf; + +{{ wiki_js_common() }} +} +{% endif %} diff --git a/roles/wiki_js-and-nginx/vardef.json b/roles/wiki_js-and-nginx/vardef.json new file mode 100644 index 0000000..81b266d --- /dev/null +++ b/roles/wiki_js-and-nginx/vardef.json @@ -0,0 +1,19 @@ +{ + "domain": { + "type": "string", + "mandatory": false + }, + "internal_port": { + "type": "integer", + "mandatory": false + }, + "tls_mode": { + "type": "string", + "options": [ + "disable", + "enable", + "force" + ], + "mandatory": false + } +} diff --git a/roles/wiki_js/defaults/main.json b/roles/wiki_js/defaults/main.json new file mode 100644 index 0000000..2de7c99 --- /dev/null +++ b/roles/wiki_js/defaults/main.json @@ -0,0 +1,36 @@ +{ + "var_wiki_js_port": 5632, + "var_wiki_js_distributed": false, + "var_wiki_js_domain": "wiki-js.example.org", + "var_wiki_js_user": "wiki_js", + "var_wiki_js_directory": "/opt/wiki_js", + "var_wiki_js_data_path": "/var/wiki_js/data", + "var_wiki_js_log_level": "info", + "var_wiki_js_log_format": "default", + "var_wiki_js_database_kind": "sqlite", + "var_wiki_js_database_data_sqlite_path": "/var/wiki_js/data.sqlite", + "var_wiki_js_database_data_postgresql_host": "postgresql.example.org", + "var_wiki_js_database_data_postgresql_port": 5432, + "var_wiki_js_database_data_postgresql_username": "wiki_js_user", + "var_wiki_js_database_data_postgresql_password": "REPLACE_ME", + "var_wiki_js_database_data_postgresql_schema": "wiki_js", + "var_wiki_js_authentication_kind": "internal", + "var_wiki_js_authentication_data_authelia_provider_id": "authelia", + "var_wiki_js_authentication_data_authelia_provider_name": "Authelia", + "var_wiki_js_authentication_data_authelia_client_id": "wiki_js", + "var_wiki_js_authentication_data_authelia_client_secret": "REPLACE_ME", + "var_wiki_js_authentication_data_authelia_url_base": "https://authelia.example.org", + "var_wiki_js_smtp_host": "smtp.example.org", + "var_wiki_js_smtp_port": 465, + "var_wiki_js_smtp_username": "REPLACE_ME", + "var_wiki_js_smtp_password": "REPLACE_ME", + "var_wiki_js_email_sending_sender_name": "Wiki.js", + "var_wiki_js_email_sending_sender_email_address": "wiki-js@example.org", + "var_wiki_js_admin_email_address": "wiki-js-admin@example.org", + "var_wiki_js_admin_password": "REPLACE_ME", + "var_wiki_js_additional_locales": [], + "var_wiki_js_user_group_name": "Default", + "var_wiki_js_allow_guest_view": true, + "var_wiki_js_dark_mode": false, + "var_wiki_js_toc_position": "left" +} diff --git a/roles/wiki_js/files/wiki-js-cli b/roles/wiki_js/files/wiki-js-cli new file mode 100755 index 0000000..5ae027b --- /dev/null +++ b/roles/wiki_js/files/wiki-js-cli @@ -0,0 +1,959 @@ +#!/usr/bin/env node +var _wiki_js_cli; +(function (_wiki_js_cli) { + var helpers; + (function (helpers) { + var string; + (function (string) { + /** + */ + function coin(template, arguments_) { + let result = template; + Object.entries(arguments_).forEach(([key, value]) => { + result = result.replace(new RegExp("{{" + key + "}}", "g"), value); + }); + return result; + } + string.coin = coin; + })(string = helpers.string || (helpers.string = {})); + })(helpers = _wiki_js_cli.helpers || (_wiki_js_cli.helpers = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + var helpers; + (function (helpers) { + var file; + (function (file) { + /** + */ + function read(path) { + const nm_fs = require("fs"); + return (new Promise((resolve, reject) => { + nm_fs.readFile(path, {}, (err, data) => { + if (err) { + reject(err); + } + else { + resolve(data.toString()); + } + }); + })); + } + file.read = read; + })(file = helpers.file || (helpers.file = {})); + })(helpers = _wiki_js_cli.helpers || (_wiki_js_cli.helpers = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + var helpers; + (function (helpers) { + var log; + (function (log) { + /** + */ + let enum_level; + (function (enum_level) { + enum_level["debug"] = "debug"; + enum_level["info"] = "info"; + enum_level["notice"] = "notice"; + enum_level["warning"] = "warning"; + enum_level["error"] = "error"; + })(enum_level = log.enum_level || (log.enum_level = {})); + /** + */ + const _level_order = [ + enum_level.debug, + enum_level.info, + enum_level.notice, + enum_level.warning, + enum_level.error, + ]; + /** + */ + var _threshold = enum_level.info; + /** + */ + function setup(threshold) { + _threshold = threshold; + return Promise.resolve(undefined); + } + log.setup = setup; + /** + */ + function write(level, incident, details) { + if (_level_order.indexOf(level) < _level_order.indexOf(_threshold)) { + // do nothing + } + else { + process.stderr.write(_wiki_js_cli.helpers.string.coin("\n<{{datetime}}> [{{level}}] {{incident}}\n{{details}}\n\n", { + "datetime": (new Date()).toISOString(), + "level": level, + "incident": incident, + "details": JSON.stringify(details, undefined, "\t"), + })); + } + } + log.write = write; + })(log = helpers.log || (helpers.log = {})); + })(helpers = _wiki_js_cli.helpers || (_wiki_js_cli.helpers = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + var helpers; + (function (helpers) { + var http; + (function (http) { + /** + */ + async function call(http_request) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.debug, "http_call_request", http_request); + const fetch_request = new Request(http_request.target, { + "method": http_request.method, + "headers": http_request.headers, + "body": http_request.body, + }); + const fetch_response = await fetch(fetch_request); + const http_response = { + "status_code": fetch_response.status, + "headers": Object.fromEntries(fetch_response.headers.entries()), + "body": await fetch_response.text(), + }; + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.debug, "http_call_response", http_response); + return http_response; + } + http.call = call; + })(http = helpers.http || (helpers.http = {})); + })(helpers = _wiki_js_cli.helpers || (_wiki_js_cli.helpers = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + var helpers; + (function (helpers) { + var args; + (function (args) { + /** + */ + function parse(args_raw) { + let result = { + "positional": [], + "volatile": {}, + }; + let state = "free"; + let key = null; + args_raw.forEach((arg_raw) => { + switch (state) { + case "free": { + if (arg_raw.startsWith("-")) { + key = arg_raw.slice(1); + state = "bound"; + } + else { + if (key === null) { + result.positional.push(arg_raw); + key = null; + state = "free"; + } + else { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.warning, "arg_discarded", { + "arg_raw": arg_raw, + }); + key = null; + state = "free"; + } + } + break; + } + case "bound": { + if (!(key in result["volatile"])) { + result["volatile"][key] = []; + } + else { + // do nothing + } + result["volatile"][key].push(arg_raw); + key = null; + state = "free"; + } + } + }); + return result; + } + args.parse = parse; + })(args = helpers.args || (helpers.args = {})); + })(helpers = _wiki_js_cli.helpers || (_wiki_js_cli.helpers = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + var conf; + (function (conf) { + /** + */ + var _data = null; + /** + */ + async function load(path) { + let data_raw; + if (path === null) { + data_raw = {}; + } + else { + const content = await _wiki_js_cli.helpers.file.read(path); + data_raw = JSON.parse(content); + } + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.debug, "conf_raw", data_raw); + _data = { + "api": { + "url_base": (data_raw?.api?.url_base + ?? + "http://localhost:3000"), + }, + "login": { + "username": (data_raw?.login?.username + ?? + "admin"), + "password": (data_raw?.login?.password + ?? + "admin"), + }, + "log": { + "threshold": (data_raw?.log?.threshold + ?? + "info"), + } + }; + return Promise.resolve(undefined); + } + conf.load = load; + /** + */ + function set(data) { + _data = data; + } + conf.set = set; + /** + */ + function get() { + return _data; + } + conf.get = get; + })(conf = _wiki_js_cli.conf || (_wiki_js_cli.conf = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + var api; + (function (api) { + /** + */ + var _login_token = null; + /** + */ + var _url_base = null; + /** + */ + function init(url_base) { + _url_base = url_base; + return Promise.resolve(undefined); + } + api.init = init; + /** + */ + async function call_generic_graphql(graphql_query, options) { + options = Object.assign({ + "variables": {}, + }, options); + const http_request = { + "target": (_url_base + "/graphql"), + "method": "POST", + "headers": Object.assign({ + "Content-Type": "application/json", + }, ((_login_token === null) + ? + {} + : + { "Cookie": ("jwt=" + _login_token) })), + "body": JSON.stringify([ + { + "operationName": null, + "variables": options.variables, + "extensions": {}, + "query": graphql_query, + } + ]), + }; + const http_response = await _wiki_js_cli.helpers.http.call(http_request); + const data = JSON.parse(http_response.body); + return Promise.resolve(data[0]["data"]); + } + /** + */ + async function call_finalize(admin_email, admin_password, site_url, telemetry) { + const http_request = { + "target": (_wiki_js_cli.conf.get().api.url_base + "/finalize"), + "method": "POST", + "headers": { + "Content-Type": "application/json", + }, + "body": JSON.stringify({ + "adminEmail": admin_email, + "adminPassword": admin_password, + "adminPasswordConfirm": admin_password, + "siteUrl": site_url, + "telemetry": telemetry, + }), + }; + const http_response = await _wiki_js_cli.helpers.http.call(http_request); + const data = JSON.parse(http_response.body); + return Promise.resolve(undefined); + } + api.call_finalize = call_finalize; + /** + * executes a local login + */ + async function call_login_local(username, password) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_login_local", {}); + return (call_generic_graphql("mutation ($username: String!, $password: String!, $strategy: String!) {authentication {login(username: $username, password: $password, strategy: $strategy) {responseResult {succeeded errorCode slug message __typename} jwt mustChangePwd mustProvideTFA mustSetupTFA continuationToken redirect tfaQRImage __typename} __typename}}", { + "variables": { + "strategy": "local", + "username": username, + "password": password, + } + }) + .then((data) => { + if (data["authentication"]["login"]["responseResult"]["succeeded"]) { + _login_token = data["authentication"]["login"]["jwt"]; + return Promise.resolve(undefined); + } + else { + return Promise.reject(new Error("login failed")); + } + })); + } + api.call_login_local = call_login_local; + /** + */ + function call_email_settings_set(settings) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_email_settings_set", { + "settings": settings, + }); + return (call_generic_graphql("mutation ($senderName: String!, $senderEmail: String!, $host: String!, $port: Int!, $name: String!, $secure: Boolean!, $verifySSL: Boolean!, $user: String!, $pass: String!, $useDKIM: Boolean!, $dkimDomainName: String!, $dkimKeySelector: String!, $dkimPrivateKey: String!) {mail {updateConfig(senderName: $senderName, senderEmail: $senderEmail, host: $host, port: $port, name: $name, secure: $secure, verifySSL: $verifySSL, user: $user, pass: $pass, useDKIM: $useDKIM, dkimDomainName: $dkimDomainName, dkimKeySelector: $dkimKeySelector, dkimPrivateKey: $dkimPrivateKey) {responseResult {succeeded errorCode slug message __typename} __typename} __typename}}", { + "variables": { + "senderName": settings.sender_name, + "senderEmail": settings.sender_email_address, + "host": settings.smtp_host, + "port": settings.smtp_port, + "name": settings.name, + "secure": settings.secure, + "verifySSL": settings.verify_ssl, + "user": settings.smtp_username, + "pass": settings.smtp_password, + "useDKIM": settings.use_dkim, + "dkimDomainName": settings.dkim_domain_name, + "dkimKeySelector": settings.dkim_key_selector, + "dkimPrivateKey": settings.dkim_private_key, + } + })); + } + api.call_email_settings_set = call_email_settings_set; + /** + */ + function call_locale_download(locale) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_locale_download", { + "locale": locale, + }); + return (call_generic_graphql("mutation ($locale: String!) {localization {downloadLocale(locale: $locale) {responseResult {succeeded errorCode slug message __typename} __typename}__typename}}", { + "variables": { + "locale": locale, + } + })); + } + api.call_locale_download = call_locale_download; + /** + */ + function call_group_list(name) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_group_list", {}); + return (call_generic_graphql("{groups {list {id name isSystem userCount createdAt updatedAt __typename} __typename}}", { + "variables": {} + })); + } + api.call_group_list = call_group_list; + /** + */ + function call_group_create(name) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_group_create", { + "name": name, + }); + return (call_generic_graphql("mutation ($name: String!) {groups {create(name: $name) {responseResult {succeeded errorCode slug message __typename} group {id name createdAt updatedAt __typename} __typename} __typename}}", { + "variables": { + "name": name, + } + })); + } + api.call_group_create = call_group_create; + /** + * @param permissions_general { + * Array< + * string + * > + * } + * @param permissions_page_specific { + * Array< + * { + * id:string; + * path:string; + * roles:Array< + * string + * >; + * match:string; + * deny:boolean; + * locales:Array< + * string + * >; + * } + * > + * } + */ + function call_group_update(group_id, name, permissions_general, permissions_page_specific) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_group_update", {}); + return (call_generic_graphql("mutation ($id: Int!, $name: String!, $redirectOnLogin: String!, $permissions: [String]!, $pageRules: [PageRuleInput]!) {groups {update(id: $id, name: $name, redirectOnLogin: $redirectOnLogin, permissions: $permissions, pageRules: $pageRules) {responseResult {succeeded errorCode slug message __typename} __typename} __typename}}", { + "variables": { + "id": group_id, + "name": name, + "redirectOnLogin": "/", + "permissions": permissions_general, + "pageRules": permissions_page_specific, + } + })); + } + api.call_group_update = call_group_update; + /** + */ + function call_authentication_strategy_list() { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_authentication_strategy_list", {}); + return (call_generic_graphql("{authentication {activeStrategies {key strategy {key title description useForm logo website __typename} config {key value __typename} order isEnabled displayName selfRegistration domainWhitelist autoEnrollGroups __typename} __typename}}", {}) + .then((data) => Promise.resolve(data["authentication"]["activeStrategies"]))); + } + api.call_authentication_strategy_list = call_authentication_strategy_list; + /** + */ + function call_authentication_strategy_set(strategies) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_authentication_strategy_set", { + "strategies": strategies, + }); + return (call_generic_graphql("mutation ($strategies: [AuthenticationStrategyInput]!) {authentication {updateStrategies(strategies: $strategies) {responseResult {succeeded errorCode slug message __typename} __typename} __typename}}", { + "variables": { + "strategies": strategies, + } + })); + } + api.call_authentication_strategy_set = call_authentication_strategy_set; + /** + */ + function call_theming_set(dark_mode, toc_position) { + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.info, "api_call_theming_set", { + "dark_mode": dark_mode, + "toc_position": toc_position, + }); + return (call_generic_graphql("mutation ($theme: String!, $iconset: String!, $darkMode: Boolean!, $tocPosition: String, $injectCSS: String, $injectHead: String, $injectBody: String) {theming {setConfig(theme: $theme, iconset: $iconset, darkMode: $darkMode, tocPosition: $tocPosition, injectCSS: $injectCSS, injectHead: $injectHead, injectBody: $injectBody) {responseResult {succeeded errorCode slug message __typename} __typename} __typename}}", { + "variables": { + "theme": "default", + "iconset": "mdi", + "darkMode": dark_mode, + "tocPosition": toc_position, + "injectCSS": "", + "injectHead": "", + "injectBody": "" + } + })); + } + api.call_theming_set = call_theming_set; + })(api = _wiki_js_cli.api || (_wiki_js_cli.api = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + var logic; + (function (logic) { + /** + */ + async function login(options = {}) { + options = Object.assign({ + "username": _wiki_js_cli.conf.get().login.username, + "password": _wiki_js_cli.conf.get().login.password, + }, options); + await _wiki_js_cli.api.call_login_local(options.username, options.password); + return Promise.resolve(undefined); + } + logic.login = login; + /** + */ + async function initialize(admin_email_address, admin_password, options = {}) { + options = Object.assign({ + "site_url": "http://localhost:3000", + "allow_telemetry": false, + }, options); + await _wiki_js_cli.api.call_finalize(admin_email_address, admin_password, options.site_url, options.allow_telemetry); + return Promise.resolve(undefined); + } + logic.initialize = initialize; + /** + */ + async function email_settings_set(smtp_host, smtp_port, smtp_username, smtp_password, sender_name, sender_email_address, options = {}) { + options = Object.assign({}, options); + const result = await _wiki_js_cli.api.call_email_settings_set({ + "sender_name": sender_name, + "sender_email_address": sender_email_address, + "smtp_host": smtp_host, + "smtp_port": smtp_port, + "secure": true, + "verify_ssl": true, + "smtp_username": smtp_username, + "smtp_password": smtp_password, + "name": "", + "use_dkim": false, + "dkim_domain_name": "", + "dkim_key_selector": "", + "dkim_private_key": "", + }); + return Promise.resolve(undefined); + } + logic.email_settings_set = email_settings_set; + /** + */ + async function locale_add(locale_code) { + _wiki_js_cli.api.call_locale_download(locale_code); + return Promise.resolve(undefined); + } + logic.locale_add = locale_add; + /** + */ + async function group_identify(name) { + const data = await _wiki_js_cli.api.call_group_list(name); + const hits = (data["groups"]["list"] + .filter((entry) => (entry["name"] === name))); + if (hits.length !== 1) { + return Promise.reject(new Error("not found or ambiguous")); + } + else { + return Promise.resolve(hits[0]["id"]); + } + } + logic.group_identify = group_identify; + /** + * returns the ID of the generated group + */ + async function group_add(name, options = {}) { + options = Object.assign({ + "permissions_general": [], + "permissions_specific": [], + }, options); + const result_1 = await _wiki_js_cli.api.call_group_create(name); + const id = result_1["groups"]["create"]["group"]["id"]; + const result_2 = await _wiki_js_cli.api.call_group_update(id, name, options.permissions_general, options.permissions_specific); + return Promise.resolve(id); + } + logic.group_add = group_add; + /** + */ + async function group_modify(id, options = {}) { + options = Object.assign({ + "permissions_general": [], + "permissions_specific": [], + }, options); + const result = await _wiki_js_cli.api.call_group_update(id, name, options.permissions_general, options.permissions_specific); + return Promise.resolve(undefined); + } + logic.group_modify = group_modify; + /** + */ + async function authentication_strategy_list() { + const result = await _wiki_js_cli.api.call_authentication_strategy_list(); + return Promise.resolve(result); + } + logic.authentication_strategy_list = authentication_strategy_list; + /** + */ + async function authentication_strategy_add(strategy) { + const current = await _wiki_js_cli.api.call_authentication_strategy_list(); + const result = await _wiki_js_cli.api.call_authentication_strategy_set(((current + .map((entry) => ({ + "key": entry["key"], + "strategyKey": entry["strategy"]["key"], + "displayName": entry["displayName"], + "order": entry["order"], + "isEnabled": entry["isEnabled"], + "config": (entry["config"] + .map((item) => ({ + "key": item["key"], + "value": JSON.stringify({ "v": JSON.parse(item["value"])["value"] }), + }))), + "selfRegistration": entry["selfRegistration"], + "domainWhitelist": entry["domainWhitelist"], + "autoEnrollGroups": entry["autoEnrollGroups"], + }))) + .concat([ + { + "key": strategy.key, + "strategyKey": "oauth2", + "displayName": strategy.name, + "order": ((current + .map(x => x["order"]) + .reduce((x, y) => (((x === null) || (x < y)) ? y : x), null)) + + + 1), + "isEnabled": true, + "config": [ + { + "key": "clientId", + "value": JSON.stringify({ "v": strategy.client_id }), + }, + { + "key": "clientSecret", + "value": JSON.stringify({ "v": strategy.client_secret }), + }, + { + "key": "authorizationURL", + "value": JSON.stringify({ "v": strategy.authorization_url }), + }, + { + "key": "tokenURL", + "value": JSON.stringify({ "v": strategy.token_url }), + }, + { + "key": "userInfoURL", + "value": JSON.stringify({ "v": strategy.user_info_url }), + }, + { + "key": "userIdClaim", + "value": JSON.stringify({ "v": "id" }), + }, + { + "key": "displayNameClaim", + "value": JSON.stringify({ "v": "name" }), + }, + { + "key": "emailClaim", + "value": JSON.stringify({ "v": "email" }), + }, + { + "key": "mapGroups", + "value": JSON.stringify({ "v": false }), + }, + { + "key": "groupsClaim", + "value": JSON.stringify({ "v": "groups" }), + }, + { + "key": "logoutURL", + "value": JSON.stringify({ "v": "" }), + }, + { + "key": "scope", + "value": JSON.stringify({ "v": "openid profile email" }), + }, + { + "key": "useQueryStringForAccessToken", + "value": JSON.stringify({ "v": false }), + }, + { + "key": "enableCSRFProtection", + "value": JSON.stringify({ "v": true }), + } + ], + "selfRegistration": true, + "domainWhitelist": [], + "autoEnrollGroups": await Promise.all(strategy.group_assignments + .map(x => group_identify(x))), + }, + ]))); + return Promise.resolve(undefined); + } + logic.authentication_strategy_add = authentication_strategy_add; + /** + */ + async function theming_set(options = {}) { + options = Object.assign({ + "dark_mode": false, + "toc_position": "left", + }, options); + const result = await _wiki_js_cli.api.call_theming_set(options.dark_mode, options.toc_position); + return Promise.resolve(result); + } + logic.theming_set = theming_set; + })(logic = _wiki_js_cli.logic || (_wiki_js_cli.logic = {})); +})(_wiki_js_cli || (_wiki_js_cli = {})); +var _wiki_js_cli; +(function (_wiki_js_cli) { + /** + */ + function parse_boolean(indicator) { + if ((indicator === "1") + || + (indicator === "yes") + || + (indicator === "on") + || + (indicator === "true")) { + return true; + } + else { + if ((indicator === "0") + || + (indicator === "no") + || + (indicator === "off") + || + (indicator === "false")) { + return false; + } + else { + throw (new Error("invalid boolean indicator: " + indicator)); + } + } + } + /** + */ + async function main(args_raw) { + // args + const args = _wiki_js_cli.helpers.args.parse(args_raw); + const override_url_base = ((("b" in args.volatile) + && + (args.volatile["b"].length >= 0)) + ? + args.volatile["b"][0] + : + null); + const override_username = ((("u" in args.volatile) + && + (args.volatile["u"].length >= 0)) + ? + args.volatile["u"][0] + : + null); + const override_password = ((("p" in args.volatile) + && + (args.volatile["p"].length >= 0)) + ? + args.volatile["p"][0] + : + null); + const override_log_level = ((("l" in args.volatile) + && + (args.volatile["l"].length >= 0)) + ? + args.volatile["l"][0] + : + null); + // conf + const conf_path = ((("c" in args.volatile) + && + (args.volatile["c"].length >= 0)) + ? + args.volatile["c"][0] + : + null); + await _wiki_js_cli.conf.load(conf_path); + _wiki_js_cli.helpers.log.write(_wiki_js_cli.helpers.log.enum_level.debug, "conf", _wiki_js_cli.conf.get()); + // init + await _wiki_js_cli.helpers.log.setup(override_log_level ?? _wiki_js_cli.conf.get().log.threshold); + await _wiki_js_cli.api.init((override_url_base ?? _wiki_js_cli.conf.get().api.url_base)); + // exec + if (args.positional.length < 1) { + return Promise.reject("SYNTAX: [node] cli.js [-c ] [-b ] [-u ] [-p ] [ [ […]]]\n\n\t = init | email-settings-set | locale-add | group-add | group-modify | auth-strat-add-oauth2 | theming-set"); + } + else { + const action = args.positional[0]; + switch (action) { + default: { + return Promise.reject("invalid action: " + action); + break; + } + case "init": { + if (args.positional.length <= 2) { + return Promise.reject("SYNTAX: … init [ []]"); + } + else { + const admin_email_address = args.positional[1]; + const admin_password = args.positional[2]; + const site_url = ((args.positional.length >= 4) + ? + args.positional[3] + : + undefined); + const allow_telemetry = ((args.positional.length >= 5) + ? + parse_boolean(args.positional[4]) + : + undefined); + await _wiki_js_cli.logic.initialize(admin_email_address, admin_password, { + "site_url": site_url, + "allow_telemetry": allow_telemetry + }); + return Promise.resolve(undefined); + } + break; + } + case "email-settings-set": { + if (args.positional.length <= 6) { + return Promise.reject("SYNTAX: … email-settings-set "); + } + else { + const smtp_host = args.positional[1]; + const smtp_port = parseInt(args.positional[2]); + const smtp_username = args.positional[3]; + const smtp_password = args.positional[4]; + const sender_name = args.positional[5]; + const sender_email_address = args.positional[6]; + await _wiki_js_cli.logic.login({ + "username": override_username, + "password": override_password, + }); + await _wiki_js_cli.logic.email_settings_set(smtp_host, smtp_port, smtp_username, smtp_password, sender_name, sender_email_address, {}); + return Promise.resolve(undefined); + } + break; + } + case "locale-add": { + if (args.positional.length <= 1) { + return Promise.reject("SYNTAX: … locale-add "); + } + else { + const locale_code = args.positional[1]; + await _wiki_js_cli.logic.login({ + "username": override_username, + "password": override_password, + }); + await _wiki_js_cli.logic.locale_add(locale_code); + return Promise.resolve(undefined); + } + break; + } + case "group-add": { + if (args.positional.length <= 2) { + return Promise.reject("SYNTAX: … group-add "); + } + else { + const name = args.positional[1]; + const permissions = args.positional[2].split(","); + await _wiki_js_cli.logic.login({ + "username": override_username, + "password": override_password, + }); + const result = await _wiki_js_cli.logic.group_add(name, { + "permissions_general": permissions, + "permissions_specific": [ + { + "id": "default", + "path": "", + "roles": permissions, + "match": "START", + "deny": false, + "locales": [] + } + ], + }); + process.stdout.write(JSON.stringify(result, undefined, "\t") + + + "\n"); + } + break; + } + case "group-modify": { + if (args.positional.length <= 2) { + return Promise.reject("SYNTAX: … group-modify "); + } + else { + const name = args.positional[1]; + const permissions = args.positional[2].split(","); + const id = await _wiki_js_cli.logic.group_identify(name); + await _wiki_js_cli.logic.login({ + "username": override_username, + "password": override_password, + }); + const result = await _wiki_js_cli.logic.group_modify(id, { + "permissions_general": permissions, + "permissions_specific": [ + { + "id": "default", + "path": "", + "roles": permissions, + "match": "START", + "deny": false, + "locales": [] + } + ], + }); + } + break; + } + case "auth-strat-add-oauth2": { + if (args.positional.length <= 8) { + return Promise.reject("SYNTAX: … auth-strat-add-oauth2 "); + } + else { + const strategy = { + "key": args.positional[1], + "name": args.positional[2], + "client_id": args.positional[3], + "client_secret": args.positional[4], + "authorization_url": args.positional[5], + "token_url": args.positional[6], + "user_info_url": args.positional[7], + "group_assignments": args.positional[8].split(","), + }; + await _wiki_js_cli.logic.login({ + "username": override_username, + "password": override_password, + }); + await _wiki_js_cli.logic.authentication_strategy_add(strategy); + return Promise.resolve(undefined); + } + break; + } + case "theming-set": { + if (args.positional.length <= 1) { + return Promise.reject("SYNTAX: … theming-set []"); + } + else { + const dark_mode = parse_boolean(args.positional[1]); + const toc_position_raw = ((args.positional.length <= 2) + ? + "left" + : + args.positional[2]); + const toc_position = (() => { + switch (toc_position_raw) { + case "left": return "left"; + case "right": return "right"; + case "hidden": return "off"; + default: { + return null; + } + } + })(); + if (toc_position === null) { + return Promise.reject("invalid toc-position: " + toc_position_raw + "; valid values are: left,right,hidden"); + } + else { + await _wiki_js_cli.logic.login({ + "username": override_username, + "password": override_password, + }); + await _wiki_js_cli.logic.theming_set({ + "dark_mode": dark_mode, + "toc_position": toc_position, + }); + return Promise.resolve(undefined); + } + } + break; + } + } + } + } + _wiki_js_cli.main = main; +})(_wiki_js_cli || (_wiki_js_cli = {})); +(_wiki_js_cli.main(process.argv.slice(2)) + .then(() => { +}) + .catch((reason) => { + process.stderr.write("-- " + String(reason) + "\n"); +})); diff --git a/roles/wiki_js/info.md b/roles/wiki_js/info.md new file mode 100644 index 0000000..0a44b8a --- /dev/null +++ b/roles/wiki_js/info.md @@ -0,0 +1,19 @@ +## Beschreibung + +- Einrichtung der Aufgaben-Verwaltung [Wiki.js](https://js.wiki/) + + +## Verweise + +- [Wiki.js-Dokumentation | Linux-Installation](https://docs.requarks.io/install/linux) +- [Wiki.js-Dokumentation | Konfiguration](https://docs.requarks.io/install/config) + + +## Anmerkungen + +- `files/wiki-js-cli` stammt aus dem Projekt [wiki-js-cli](https://forgejo.linke.sx/misc/wiki-js-cli) + + +## ToDo + +- start page diff --git a/roles/wiki_js/tasks/main.json b/roles/wiki_js/tasks/main.json new file mode 100644 index 0000000..019b07a --- /dev/null +++ b/roles/wiki_js/tasks/main.json @@ -0,0 +1,193 @@ +[ + { + "name": "packages", + "become": true, + "ansible.builtin.apt": { + "update_cache": true, + "pkg": [ + "npm" + ] + } + }, + { + "name": "user", + "become": true, + "ansible.builtin.user": { + "name": "{{var_wiki_js_user}}", + "create_home": true, + "home": "{{var_wiki_js_directory}}" + } + }, + { + "name": "directories", + "become": true, + "loop": [ + "{{var_wiki_js_data_path}}" + ], + "ansible.builtin.file": { + "owner": "{{var_wiki_js_user}}", + "state": "directory", + "path": "{{item}}" + } + }, + { + "name": "download", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.get_url": { + "url": "https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz", + "dest": "/tmp/wiki_js.tar.gz" + } + }, + { + "name": "unpack", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.unarchive": { + "remote_src": true, + "src": "/tmp/wiki_js.tar.gz", + "dest": "{{var_wiki_js_directory}}" + } + }, + { + "name": "cli client", + "become": true, + "ansible.builtin.copy": { + "src": "wiki-js-cli", + "dest": "/usr/local/bin/wiki-js-cli", + "mode": "0700" + } + }, + { + "name": "database | sqlite | dirctory", + "when": "var_wiki_js_database_kind == 'sqlite'", + "become": true, + "ansible.builtin.file": { + "path": "{{var_wiki_js_database_data_sqlite_path | dirname}}", + "state": "directory", + "owner": "{{var_wiki_js_user}}" + } + }, + { + "name": "database | sqlite | file", + "when": "var_wiki_js_database_kind == 'sqlite'", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.file": { + "path": "{{var_wiki_js_database_data_sqlite_path}}", + "state": "touch" + } + }, + { + "name": "conf", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.template": { + "src": "config.yml.j2", + "dest": "{{var_wiki_js_directory}}/config.yml" + } + }, + { + "name": "database | sqlite | setup", + "when": "var_wiki_js_database_kind == 'sqlite'", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "npm rebuild sqlite3" + } + }, + { + "name": "systemd-unit", + "become": true, + "ansible.builtin.template": { + "src": "systemd-unit.j2", + "dest": "/etc/systemd/system/wiki_js.service" + } + }, + { + "name": "start service", + "become": true, + "ansible.builtin.systemd_service": { + "state": "restarted", + "enabled": true, + "name": "wiki_js" + } + }, + { + "name": "setup | initialize", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} init {{var_wiki_js_admin_email_address}} {{var_wiki_js_admin_password}} https://{{var_wiki_js_domain}} no" + } + }, + { + "name": "setup | email settings", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} -u {{var_wiki_js_admin_email_address}} -p {{var_wiki_js_admin_password}} email-settings-set {{var_wiki_js_smtp_host}} {{var_wiki_js_smtp_port}} {{var_wiki_js_smtp_username}} {{var_wiki_js_smtp_password}} {{email_sending_sender_name}} {{email_sending_sender_email_address}}" + } + }, + { + "name": "setup | locales", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "loop": "{{var_wiki_js_additional_locales}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} -u {{var_wiki_js_admin_email_address}} -p {{var_wiki_js_admin_password}} locale-add {{item}}" + } + }, + { + "name": "setup | set guest access | negative", + "when": "not var_wiki_js_allow_guest_view", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} -u {{var_wiki_js_admin_email_address}} -p {{var_wiki_js_admin_password}} group-modify Guests" + } + }, + { + "name": "setup | set guest access | positive", + "when": "var_wiki_js_allow_guest_view", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} -u {{var_wiki_js_admin_email_address}} -p {{var_wiki_js_admin_password}} group-modify Guests read:pages read:assets read:comments" + } + }, + { + "name": "setup | define user group", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} -u {{var_wiki_js_admin_email_address}} -p {{var_wiki_js_admin_password}} group-add {{var_wiki_js_user_group_name}} {{var_wiki_js_allow_guest_view | ternary('read:pages,read:assets,read:comments,write:comments,write:pages,manage:pages,delete:pages,write:styles,write:scripts,read:source,read:history,write:assets,manage:assets,manage:comments','')}}" + } + }, + { + "name": "setup | authentication | authelia", + "when": "var_wiki_js_authentication_kind == 'authelia'", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} -u {{var_wiki_js_admin_email_address}} -p {{var_wiki_js_admin_password}} auth-strat-add-oauth2 {{var_wiki_js_authentication_data_authelia_provider_id}} {{var_wiki_js_authentication_data_authelia_provider_name}} {{var_wiki_js_authentication_data_authelia_client_id}} {{var_wiki_js_authentication_data_authelia_client_secret}} {{var_wiki_js_authentication_data_authelia_url_base}}/api/oidc/authorization {{var_wiki_js_authentication_data_authelia_url_base}}/api/oidc/token {{var_wiki_js_authentication_data_authelia_url_base}}/api/oidc/userinfo {{var_wiki_js_user_group_name}}" + } + }, + { + "name": "setup | theming", + "become": true, + "become_user": "{{var_wiki_js_user}}", + "ansible.builtin.command": { + "chdir": "{{var_wiki_js_directory}}", + "cmd": "/usr/local/bin/wiki-js-cli -b http://127.0.0.1:{{var_wiki_js_port | string}} -u {{var_wiki_js_admin_email_address}} -p {{var_wiki_js_admin_password}} theming-set {{var_wiki_js_dark_mode | ternary('yes','no')}} {{var_wiki_js_toc_position}}" + } + } +] diff --git a/roles/wiki_js/templates/config.yml.j2 b/roles/wiki_js/templates/config.yml.j2 new file mode 100644 index 0000000..b52747a --- /dev/null +++ b/roles/wiki_js/templates/config.yml.j2 @@ -0,0 +1,49 @@ +port: {{var_wiki_js_port | string}} + +{% if var_wiki_js_database_kind == 'sqlite' %} +db: + type: sqlite + storage: {{var_wiki_js_database_data_sqlite_path}} +{% endif %} + +{% if var_wiki_js_database_kind == 'postgresql' %} +db: + type: postgres + host: {{var_wiki_js_database_data_postgresql_host}} + port: {{var_wiki_js_database_data_postgresql_port | to_yaml}} + user: {{var_wiki_js_database_data_postgresql_username}} + pass: {{var_wiki_js_database_data_postgresql_password}} + db: {{var_wiki_js_database_data_postgresql_schema}} + ssl: false + # schema: public +{% endif %} + +ssl: + enabled: false + port: 3443 + + # Provider to use, possible values: custom, letsencrypt + provider: custom + + format: pem + key: path/to/key.pem + cert: path/to/cert.pem + pfx: path/to/cert.pfx + passphrase: null + dhparam: null + + domain: wiki.yourdomain.com + subscriberEmail: admin@example.com + +bindIP: 0.0.0.0 + +logLevel: {{var_wiki_js_log_level}} +logFormat: {{var_wiki_js_log_format}} + +offline: false + +ha: {{var_wiki_js_distributed | to_yaml}} + +dataPath: {{var_wiki_js_data_path}} + +bodyParserLimit: 5mb diff --git a/roles/wiki_js/templates/systemd-unit.j2 b/roles/wiki_js/templates/systemd-unit.j2 new file mode 100644 index 0000000..3d6433a --- /dev/null +++ b/roles/wiki_js/templates/systemd-unit.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=Wiki.js +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/node server +Restart=always +User={{var_wiki_js_user}} +Environment=NODE_ENV=production +WorkingDirectory={{var_wiki_js_directory}} + +[Install] +WantedBy=multi-user.target diff --git a/roles/wiki_js/vardef.json b/roles/wiki_js/vardef.json new file mode 100644 index 0000000..6bb5756 --- /dev/null +++ b/roles/wiki_js/vardef.json @@ -0,0 +1,162 @@ +{ + "port": { + "mandatory": false, + "type": "integer" + }, + "distributed": { + "mandatory": false, + "type": "boolean" + }, + "domain": { + "mandatory": false, + "type": "string" + }, + "user": { + "mandatory": false, + "type": "string" + }, + "directory": { + "mandatory": false, + "type": "string" + }, + "log_level": { + "mandatory": false, + "type": "string", + "options": [ + "error", + "warn", + "info", + "verbose", + "debug", + "silly" + ] + }, + "log_format": { + "mandatory": false, + "type": "string", + "options": [ + "default", + "json" + ] + }, + "data_path": { + "mandatory": false, + "type": "string" + }, + "database_kind": { + "mandatory": false, + "type": "string", + "options": [ + "sqlite", + "postgresql" + ] + }, + "database_data_sqlite_path": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_host": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_port": { + "mandatory": false, + "type": "integer" + }, + "database_data_postgresql_username": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_password": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_schema": { + "mandatory": false, + "type": "string" + }, + "authentication_kind": { + "mandatory": false, + "type": "string", + "options": [ + "internal", + "authelia" + ] + }, + "authentication_data_authelia_provider_id": { + "type": "string", + "mandatory": false + }, + "authentication_data_authelia_provider_name": { + "type": "string", + "mandatory": false + }, + "authentication_data_authelia_client_id": { + "type": "string", + "mandatory": false + }, + "authentication_data_authelia_client_secret": { + "type": "string", + "mandatory": false + }, + "authentication_data_authelia_url_base": { + "type": "string", + "mandatory": false + }, + "smtp_host": { + "mandatory": false, + "type": "string" + }, + "smtp_port": { + "mandatory": false, + "type": "integer" + }, + "smtp_username": { + "mandatory": false, + "type": "string" + }, + "smtp_password": { + "mandatory": false, + "type": "string" + }, + "email_sending_sender_name": { + "mandatory": false, + "type": "string" + }, + "email_sending_sender_email_address": { + "mandatory": false, + "type": "string" + }, + "admin_email_address": { + "mandatory": false, + "type": "string" + }, + "admin_password": { + "mandatory": false, + "type": "string" + }, + "additional_locales": { + "mandatory": false, + "type": "array", + "items": { + "nullable": false, + "type": "string" + } + }, + "user_group_name": { + "mandatory": false, + "type": "string" + }, + "allow_guest_view": { + "mandatory": false, + "type": "boolean" + }, + "dark_mode": { + "mandatory": false, + "type": "boolean" + }, + "toc_position": { + "mandatory": false, + "type": "string" + } +}