Projekt

Obecné

Profil

Stáhnout (8.45 KB) Statistiky
| Větev: | Tag: | Revize:
1
// VUE instance of certificate creation page
2
var createCertificateApp = new Vue({
3
    el: "#create-certificate-content",
4
    data: {
5
        notBefore: "",
6
        notAfter: "",
7
        isSelfSigned: false,
8
        invalidCN: false,
9
        invalidC: false,
10
        customKey: false,
11
        customExtensions: false,
12
        // available certificate authorities
13
        authorities: [],
14
        // data of the selected certificate authorities to be displayed in the form
15
        selectedCAData: {
16
            CN: "",
17
            C: "",
18
            L: "",
19
            ST: "",
20
            O: "",
21
            OU: "",
22
            emailAddress: ""
23
        },
24
        // Data of the new certificate to be created received from the input fields
25
        certificateData: {
26
            subject: {
27
                CN: "",
28
                C: "",
29
                L: "",
30
                ST: "",
31
                O: "",
32
                OU: "",
33
                emailAddress: ""
34
            },
35
            validityDays: 30,
36
            usage: {
37
                CA: false,
38
                authentication: false,
39
                digitalSignature: false,
40
                SSL: false
41
            },
42
            CA: null
43
        },
44
        extensions: null,
45
        key: {
46
            password: null,
47
            key_pem: null,
48
        },
49
        errorMessage: ""
50
    },
51
    // actions to be performed when the page is loaded
52
    // - initialize notBefore and notAfter with current date and current date + 1 month respectively
53
    async mounted() {
54
        this.notBefore = new Date().toDateInputValue(); // init notBefore to current date
55
        var endDate = new Date(new Date().getTime() + (30 * 24 * 60 * 60 * 1000));
56
        this.notAfter = endDate.toDateInputValue(); // init notAfter to notBefore + 30 days
57

    
58
        // Initialize available CA select values
59
        try {
60
            const response = await axios.get(API_URL + "certificates", {
61
                params: {
62
                    filtering: {
63
                        usage: ["CA"],
64
                    }
65
                }
66
            });
67
            if (response.data["success"]) {
68
                createCertificateApp.authorities = response.data["data"];
69
            } else {
70
                this.showError("Error occurred while downloading list of available CAs");
71
                console.error(response.data["data"]);
72
                createCertificateApp.authorities = [];
73
            }
74
        } catch (error) {
75
            this.showError("Error occurred while downloading list of available CAs");
76
            console.log(error);
77
        }
78
    },
79
    methods: {
80
        onKeyFileChange: function (event) {
81
            var file = event.target.files[0];
82
            var reader = new FileReader();
83
            reader.readAsText(file, "UTF-8");
84
            reader.onload = function (evt) {
85
                createCertificateApp.key.key_pem = evt.target.result;
86
            }
87
            reader.onerror = function (evt) {
88
                this.showError("Error occurred while reading custom private key file.");
89
            }
90

    
91
        },
92
        showError: function (message) {
93
            document.body.scrollTop = 0;
94
            document.documentElement.scrollTop = 0;
95
            this.errorMessage = message;
96
        },
97
        // handle certificate creation request
98
        onCreateCertificate: async function () {
99
            // validate input data
100
            // - validate if is self signed or CA is selected
101
            // - validate if subject CN is filled in
102
            // - validate if C is either empty or has exactly 2 characters
103
            if (!this.isSelfSigned && this.certificateData.CA == null) {
104
                this.showError("Issuer must be selected or 'Self-signed' option must be checked!")
105
                return;
106
            }
107
            if (this.certificateData.subject.CN === "") {
108
                this.showError("CN field must be filled in!")
109
                this.invalidCN = true;
110
                return;
111
            }
112
            if (this.certificateData.subject.C !== "" && this.certificateData.subject.C.length !== 2) {
113
                this.showError("C field must be empty or must have exactly 2 characters!");
114
                this.invalidC = true;
115
                return;
116
            }
117

    
118
            // populate optional key field in the request body
119
            delete this.certificateData.key;
120
            if (this.customKey && this.key.password != null && this.key.password !== "") {
121
                if (!this.certificateData.hasOwnProperty("key")) this.certificateData.key = {};
122
                this.certificateData.key.password = this.key.password;
123
            }
124
            if (this.customKey && this.key.key_pem != null) {
125
                if (!this.certificateData.hasOwnProperty("key")) this.certificateData.key = {};
126
                this.certificateData.key.key_pem = this.key.key_pem;
127
            }
128

    
129
            // populate optional extensions field in the request body
130
            delete this.certificateData.extensions;
131
            if (this.customExtensions && this.extensions !== "" && this.extensions != null)
132
            {
133
                this.certificateData.extensions = this.extensions;
134
            }
135

    
136

    
137
            this.certificateData.validityDays = parseInt(this.certificateData.validityDays);
138
            try {
139
                // create a deep copy of the certificate dataa
140
                var certificateDataCopy = JSON.parse(JSON.stringify(this.certificateData));
141
                certificateDataCopy.usage = [];
142

    
143
                // convert usage dictionary to list
144
                if (this.certificateData.usage.CA) certificateDataCopy.usage.push("CA");
145
                if (this.certificateData.usage.digitalSignature) certificateDataCopy.usage.push("digitalSignature");
146
                if (this.certificateData.usage.authentication) certificateDataCopy.usage.push("authentication");
147
                if (this.certificateData.usage.SSL) certificateDataCopy.usage.push("SSL");
148

    
149
                // call RestAPI endpoint
150
                const response = await axios.post(API_URL + "certificates", certificateDataCopy);
151
                if (response.data["success"]) {
152
                    window.location.href = "/static/index.html?success=Certificate+successfully+created";
153
                }
154
                // on error display server response message
155
                else {
156
                    console.error(response.data["data"]);
157
                    createCertificateApp.showError(response.data["data"]);
158
                }
159
            } catch (error) {
160
                createCertificateApp.showError("An error occurred while creating a certificate.");
161
                console.error(error);
162
            }
163
        }
164
    },
165
    // data watches
166
    watch: {
167
        authorities: function (val, oldVal) {
168
            this.isSelfSigned = val.length === 0;
169
        },
170
        isSelfSigned: function (val, oldVal) {
171
            if (val) {
172
                this.certificateData.CA = null;
173
                this.certificateData.usage.CA = true;
174
            } else {
175
                this.certificateData.usage.CA = false;
176
            }
177
        },
178
        // if the selected CA is changed, the Issuer input fileds must be filled in
179
        'certificateData.validityDays': function (val, oldVal) {
180
            var endDate = new Date(new Date().getTime() + (val * 24 * 60 * 60 * 1000));
181
            this.notAfter = endDate.toDateInputValue(); // init notAfter to today + validityDays
182
        },
183
        'certificateData.subject.CN': function (val, oldVal) {
184
            if (val !== '') this.invalidCN = false;
185
        },
186
        'certificateData.CA': async function (val, oldVal) {
187
            // self-signed certificate - all fields are empty
188
            if (val === "null" || val == null) {
189
                createCertificateApp.selectedCAData = {
190
                    CN: "",
191
                    C: "",
192
                    L: "",
193
                    ST: "",
194
                    O: "",
195
                    OU: "",
196
                    emailAddress: ""
197
                };
198
            }
199
            // a CA is selected - get CA's details and display them
200
            else {
201
                try {
202
                    const response = await axios.get(API_URL + "certificates/" + val + "/details");
203
                    if (response.data["success"])
204
                        createCertificateApp.selectedCAData = response.data["data"]["subject"];
205
                    else
206
                        console.log("Error occurred while fetching CA details");
207
                } catch (error) {
208
                    console.log(error);
209
                }
210
            }
211
        }
212
    }
213
});
(10-10/13)