summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-acme/htdocs/luci-static/resources/view/acme.js
blob: f9059f9472f05544c9295129f5d19ea352372a2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
'use strict';
'require form';
'require fs';
'require view';

return view.extend({
	load: function () {
		return Promise.all([
			L.resolveDefault(fs.stat('/usr/sbin/nginx'), {}),
			L.resolveDefault(fs.stat('/usr/sbin/uhttpd'), {})
		]);
	},

	render: function (stats) {
		var m, s, o;

		m = new form.Map("acme", _("ACME certificates"),
			_("This configures ACME (Letsencrypt) automatic certificate installation. " +
				"Simply fill out this to have the router configured with Letsencrypt-issued " +
				"certificates for the web interface. " +
				"Note that the domain names in the certificate must already be configured to " +
				"point at the router's public IP address. " +
				"Once configured, issuing certificates can take a while. " +
				"Check the logs for progress and any errors."));

		s = m.section(form.TypedSection, "acme", _("ACME global config"));
		s.anonymous = true

		o = s.option(form.Value, "state_dir", _("State directory"),
			_("Where certs and other state files are kept."));
		o.rmempty = false;
		o.datatype = "directory";

		o = s.option(form.Value, "account_email", _("Account email"),
			_("Email address to associate with account key."))
		o.rmempty = false;
		o.datatype = "minlength(1)";

		o = s.option(form.Flag, "debug", _("Enable debug logging"));
		o.rmempty = false;

		s = m.section(form.TypedSection, "cert", _("Certificate config"))
		s.anonymous = false;
		s.addremove = true;

		o = s.option(form.Flag, "enabled", _("Enabled"));
		o.rmempty = false;

		o = s.option(form.Flag, "use_staging", _("Use staging server"),
			_("Get certificate from the Letsencrypt staging server " +
				"(use for testing; the certificate won't be valid)."));
		o.rmempty = false;

		o = s.option(form.Flag, "use_acme_server",
			_("Custom ACME CA"), _("Use a custom CA instead of Let's Encrypt."));
		o.depends("use_staging", "0");
		o.default = false;

		o = s.option(form.Value, "acme_server", _("ACME server URL"),
			_("Custom ACME server directory URL."));
		o.depends("use_acme_server", "1");
		o.optional = true;

		o = s.option(form.ListValue, "keylength", _("Key size"),
			_("Key size (and type) for the generated certificate."));
		o.value("2048", _("RSA 2048 bits"));
		o.value("3072", _("RSA 3072 bits"));
		o.value("4096", _("RSA 4096 bits"));
		o.value("ec-256", _("ECC 256 bits"));
		o.value("ec-384", _("ECC 384 bits"));
		o.default = "2048";
		o.rmempty = false;

		if (stats[1].type === 'file') {
			o = s.option(form.Flag, "update_uhttpd", _("Use for uhttpd"),
				_("Update the uhttpd config with this certificate once issued " +
					"(only select this for one certificate). " +
					"Is also available luci-app-uhttpd to configure uhttpd form the LuCI interface."));
			o.rmempty = false;
		}

		if (stats[0].type === 'file') {
			o = s.option(form.Flag, "update_nginx", _("Use for nginx"),
				_("Update the nginx config with this certificate once issued " +
					"(only select this for one certificate). " +
					"Nginx must support ssl, if not it won't start as it needs to be " +
					"compiled with ssl support to use cert options"));
			o.rmempty = false;
		}

		o = s.option(form.Value, "webroot", _("Webroot directory"),
			_("Webserver root directory. Set this to the webserver " +
				"document root to run Acme in webroot mode. The web " +
				"server must be accessible from the internet on port 80."));
		o.optional = true;

		o = s.option(form.DynamicList, "domains", _("Domain names"),
			_("Domain names to include in the certificate. " +
				"The first name will be the subject name, subsequent names will be alt names. " +
				"Note that all domain names must point at the router in the global DNS."));
		o.datatype = "list(string)";

		s.option(form.Value, "dns", _("DNS API"),
			_("To use DNS mode to issue certificates, set this to the name of a DNS API supported by acme.sh. " +
				"See https://github.com/acmesh-official/acme.sh/wiki/dnsapi for the list of available APIs. " +
				"In DNS mode, the domain name does not have to resolve to the router IP. " +
				"DNS mode is also the only mode that supports wildcard certificates. " +
				"Using this mode requires the acme-dnsapi package to be installed."));

		o = s.option(form.DynamicList, "credentials", _("DNS API credentials"),
			_("The credentials for the DNS API mode selected above. " +
				"See https://github.com/acmesh-official/acme.sh/wiki/dnsapi for the format of credentials required by each API. " +
				"Add multiple entries here in KEY=VAL shell variable format to supply multiple credential variables."))
		o.datatype = "list(string)";

		s.option(form.Value, "calias", _("Challenge Alias"),
			_("The challenge alias to use for ALL domains. " +
				"See https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode for the details of this process. " +
				"LUCI only supports one challenge alias per certificate."));

		s.option(form.Value, "dalias", _("Domain Alias"),
			_("The domain alias to use for ALL domains. " +
				"See https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mode for the details of this process. " +
				"LUCI only supports one challenge domain per certificate."));

		return m.render()
	}
})