-
- `;
-}
-
-export default function(element, { zone }) {
- render(html`<${ZoneRecords} zone=${zone} />`, element);
-};
diff --git a/public/scripts/vendor/licenses.txt b/public/scripts/vendor/licenses.txt
deleted file mode 100644
index 602b9c6..0000000
--- a/public/scripts/vendor/licenses.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-htm@3.1.1 - Apache-2.0
- Copyright 2018 Google Inc.
- Full license: ./preact/LICENSE-htm
-
-preact@10.7.1 - MIT
- Copyright (c) 2015-present Jason Miller
- Full license: ./preact/LICENSE-preact
diff --git a/public/scripts/vendor/preact/LICENSE-htm b/public/scripts/vendor/preact/LICENSE-htm
deleted file mode 100644
index f107611..0000000
--- a/public/scripts/vendor/preact/LICENSE-htm
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright 2018 Google Inc.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
\ No newline at end of file
diff --git a/public/scripts/vendor/preact/LICENSE-preact b/public/scripts/vendor/preact/LICENSE-preact
deleted file mode 100644
index da5389a..0000000
--- a/public/scripts/vendor/preact/LICENSE-preact
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015-present Jason Miller
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/public/scripts/vendor/preact/standalone.js b/public/scripts/vendor/preact/standalone.js
deleted file mode 100644
index e24f87b..0000000
--- a/public/scripts/vendor/preact/standalone.js
+++ /dev/null
@@ -1 +0,0 @@
-var e,n,_,t,o,r,u,l={},i=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(e,n){for(var _ in n)e[_]=n[_];return e}function f(e){var n=e.parentNode;n&&n.removeChild(e)}function a(n,_,t){var o,r,u,l={};for(u in _)"key"==u?o=_[u]:"ref"==u?r=_[u]:l[u]=_[u];if(arguments.length>2&&(l.children=arguments.length>3?e.call(arguments,2):t),"function"==typeof n&&null!=n.defaultProps)for(u in n.defaultProps)void 0===l[u]&&(l[u]=n.defaultProps[u]);return p(n,l,o,r,null)}function p(e,t,o,r,u){var l={type:e,props:t,key:o,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==u?++_:u};return null!=n.vnode&&n.vnode(l),l}function h(e){return e.children}function d(e,n){this.props=e,this.context=n}function v(e,n){if(null==n)return e.__?v(e.__,e.__.__k.indexOf(e)+1):null;for(var _;n0?p(m.type,m.props,m.key,null,m.__v):m)){if(m.__=_,m.__b=_.__b+1,null===(y=H[a])||y&&m.key==y.key&&m.type===y.type)H[a]=void 0;else for(d=0;d=t.__.length&&t.__.push({}),t.__[e]}function G(e){return R=1,z(ie,e)}function z(e,n,_){var t=j(L++,2);return t.t=e,t.__c||(t.__=[_?_(n):ie(void 0,n),function(e){var n=t.t(t.__[0],e);t.__[0]!==n&&(t.__=[n,t.__[1]],t.__c.setState({}))}],t.__c=N),t.__}function J(e,_){var t=j(L++,3);!n.__s&&le(t.__H,_)&&(t.__=e,t.__H=_,N.__H.__h.push(t))}function K(e,_){var t=j(L++,4);!n.__s&&le(t.__H,_)&&(t.__=e,t.__H=_,N.__h.push(t))}function Q(e){return R=5,Y(function(){return{current:e}},[])}function X(e,n,_){R=6,K(function(){"function"==typeof e?e(n()):e&&(e.current=n())},null==_?_:_.concat(e))}function Y(e,n){var _=j(L++,7);return le(_.__H,n)&&(_.__=e(),_.__H=n,_.__h=e),_.__}function Z(e,n){return R=8,Y(function(){return e},n)}function ee(e){var n=N.context[e.__c],_=j(L++,9);return _.c=e,n?(null==_.__&&(_.__=!0,n.sub(N)),n.props.value):e.__}function ne(e,_){n.useDebugValue&&n.useDebugValue(_?_(e):e)}function _e(e){var n=j(L++,10),_=G();return n.__=e,N.componentDidCatch||(N.componentDidCatch=function(e){n.__&&n.__(e),_[1](e)}),[_[0],function(){_[1](void 0)}]}function te(){I.forEach(function(e){if(e.__P)try{e.__H.__h.forEach(re),e.__H.__h.forEach(ue),e.__H.__h=[]}catch(_){e.__H.__h=[],n.__e(_,e.__v)}}),I=[]}n.__b=function(e){N=null,O&&O(e)},n.__r=function(e){V&&V(e),L=0;var n=(N=e.__c).__H;n&&(n.__h.forEach(re),n.__h.forEach(ue),n.__h=[])},n.diffed=function(e){q&&q(e);var _=e.__c;_&&_.__H&&_.__H.__h.length&&(1!==I.push(_)&&W===n.requestAnimationFrame||((W=n.requestAnimationFrame)||function(e){var n,_=function(){clearTimeout(t),oe&&cancelAnimationFrame(n),setTimeout(e)},t=setTimeout(_,100);oe&&(n=requestAnimationFrame(_))})(te)),N=void 0},n.__c=function(e,_){_.some(function(e){try{e.__h.forEach(re),e.__h=e.__h.filter(function(e){return!e.__||ue(e)})}catch(t){_.some(function(e){e.__h&&(e.__h=[])}),_=[],n.__e(t,e.__v)}}),B&&B(e,_)},n.unmount=function(e){$&&$(e);var _=e.__c;if(_&&_.__H)try{_.__H.__.forEach(re)}catch(e){n.__e(e,_.__v)}};var oe="function"==typeof requestAnimationFrame;function re(e){var n=N;"function"==typeof e.__c&&e.__c(),N=n}function ue(e){var n=N;e.__c=e.__(),N=n}function le(e,n){return!e||e.length!==n.length||n.some(function(n,_){return n!==e[_]})}function ie(e,n){return"function"==typeof n?n(e):n}var ce=function(e,n,_,t){var o;n[0]=0;for(var r=1;r=5&&((o||!e&&5===t)&&(u.push(t,0,o,_),t=6),e&&(u.push(t,e,0,_),t=6)),o=""},i=0;i"===n?(t=1,o=""):o=n+o[0]:r?n===r?r="":o+=n:'"'===n||"'"===n?r=n:">"===n?(l(),t=1):t&&("="===n?(t=5,_=o,o=""):"/"===n&&(t<5||">"===e[i][c+1])?(l(),3===t&&(u=u[0]),t=u,(u=u[0]).push(2,0,t),t=0):" "===n||"\t"===n||"\n"===n||"\r"===n?(l(),t=2):o+=n),3===t&&"!--"===o&&(t=4,u=u[0])}return l(),u}(e)),n),arguments,[])).length>1?n:n[0]}.bind(a);export{a as h,fe as html,M as render,d as Component,F as createContext,G as useState,z as useReducer,J as useEffect,K as useLayoutEffect,Q as useRef,X as useImperativeHandle,Y as useMemo,Z as useCallback,ee as useContext,ne as useDebugValue,_e as useErrorBoundary};
diff --git a/public/styles/login.css b/public/styles/login.css
deleted file mode 100644
index d1c085f..0000000
--- a/public/styles/login.css
+++ /dev/null
@@ -1,13 +0,0 @@
-form {
- flex-grow: 1;
- max-width: 40ch;
- margin: 25vh auto 0 auto;
-}
-
-main {
- flex-direction: row;
-}
-
-h1 {
- text-align: center;
-}
diff --git a/public/styles/main.css b/public/styles/main.css
deleted file mode 100644
index 860c1bd..0000000
--- a/public/styles/main.css
+++ /dev/null
@@ -1,158 +0,0 @@
-body {
- display: flex;
- min-height: 100vh;
- min-width: 100vw;
- margin: 0;
- font-family: sans-serif;
- line-height: 1.5;
-}
-
-:root {
- --color-primary: 94, 12, 151;
- --color-hightlight-1: 255, 212, 186;
- --color-hightlight-2: 208, 44, 167;
- --color-contrast: white;
-}
-
-main {
- flex-grow: 1;
- display: flex;
- padding: 1rem;
- flex-direction: column;
-}
-
-h1 {
- margin-top: 0;
- margin-bottom: 1rem;
-}
-
-a {
- color: rgb(var(--color-primary));
- text-decoration: none;
- position: relative;
- padding-bottom: .3em;
-}
-
-a::after {
- content: "";
- display: block;
- width: 100%;
- border-bottom: 2px solid rgb(var(--color-primary));
- position: absolute;
- bottom: .1em;
- transition: .2s;
-}
-
-a:hover::after {
- bottom: .3em;
-}
-
-p.feedback {
- padding: .35rem;
- margin: 0;
-}
-
-p.feedback.error {
- background: #fddede;
- color: #710000;
-}
-
-select,
-input {
- border: 1px solid rgb(var(--color-primary));;
- border-radius: 0;
- background: var(--color-contrast);
-}
-
-select,
-button,
-input {
- padding: .35rem .35rem;
- font-size: 1rem;
-}
-
-button,
-input[type="submit"] {
- background: rgb(var(--color-primary));
- color: var(--color-contrast);
- border-left: 5px solid rgb(var(--color-hightlight-1));
- border-top: 5px solid rgb(var(--color-hightlight-1));
- border-right: 5px solid rgb(var(--color-hightlight-2));
- border-bottom: 5px solid rgb(var(--color-hightlight-2));
-}
-
-button:hover:not([disabled]),
-input[type="submit"]:hover:not([disabled]) {
- background: rgba(var(--color-primary), .8);
-}
-
-button:active:not([disabled]) ,
-input[type="submit"]:active:not([disabled]) {
- border-left: 5px solid rgb(var(--color-hightlight-2));
- border-top: 5px solid rgb(var(--color-hightlight-2));
- border-right: 5px solid rgb(var(--color-hightlight-1));
- border-bottom: 5px solid rgb(var(--color-hightlight-1));
-}
-
-button[disabled],
-input[type="submit"][disabled] {
- background: rgba(var(--color-primary), .75);
- border-left-color: rgba(var(--color-hightlight-1), .75);
- border-top-color: rgba(var(--color-hightlight-1), .75);
- border-right-color: rgba(var(--color-hightlight-2), .75);
- border-bottom-color: rgba(var(--color-hightlight-2), .75);
- cursor: not-allowed;
-}
-
-form input[type="submit"] {
- margin-top: 2rem;
-}
-
-form label {
- margin-top: .75em;
-}
-
-form {
- display: flex;
- flex-direction: column;
- width: fit-content;
-}
-
-nav.main {
- background: rgb(var(--color-primary));
- min-width: 25ch;
- display: flex;
- flex: 0;
- padding: 1rem;
- border-right: 5px solid rgb(var(--color-hightlight-2));
-}
-
-nav.main a {
- color: var(--color-contrast);
-}
-
-nav.main a::after {
- border-bottom: 2px solid var(--color-contrast);
-}
-
-
-nav.main a img {
- filter: invert(100%);
- width: 1.4em;
- margin-bottom: -.3em;
-}
-
-
-nav.main ul {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-nav.main ul li {
- margin-top: .35rem;
-}
-
-nav.main ul ul {
- margin-left: 1rem;
-}
diff --git a/public/styles/zone.css b/public/styles/zone.css
deleted file mode 100644
index 2fb3023..0000000
--- a/public/styles/zone.css
+++ /dev/null
@@ -1,183 +0,0 @@
-nav.secondary ul {
- display: flex;
- margin: 0;
- list-style: none;
- padding: 0;
-}
-
-nav.secondary li {
- margin-right: 1rem;
-}
-
-main > section {
- max-width: 120ch;
-}
-
-header {
- display: flex;
- margin: 1rem 0;
-}
-
-h2 {
- margin: 0;
- flex-grow: 1;
-}
-
-header > :not(:last-of-type) {
- margin-right: 2ch;
-}
-
-.zone-content article.rrsets-per-name {
- display: grid;
- grid-template-columns: repeat(6, 1fr);
- grid-gap: 2ch;
- margin: .5rem 0;
-}
-
-.zone-content article.rrsets-per-name:not(:last-of-type) {
- border-bottom: 2px solid rgb(var(--color-hightlight-2));
-}
-
-.zone-content h3.record-name,
-.zone-content h4.record-type {
- margin: 0;
- font-weight: normal;
- font-size: 1rem;
-}
-
-.zone-content h3.record-name {
- grid-column: 1 / 3;
-}
-
-.zone-content div.rrsets-per-type {
- grid-column: 3 / 7;
-}
-
-.zone-content article.rrset-per-type {
- grid-template-columns: repeat(4, 1fr);
- display: grid;
- grid-gap: 2ch;
-}
-
-.zone-content h4.record-type {
- grid-column: 1 / 2;
-}
-
-.zone-content ul.rrset-rdata {
- padding: 0;
- margin: 0;
- list-style-type: none;
- grid-column: 2 / 5;
-}
-
-.zone-content ul.rrset-rdata dl {
- display: grid;
- grid-template: auto / max-content 1fr;
-}
-
-.zone-content ul.rrset-rdata dd {
- margin: 0;
-}
-
-.zone-content ul.rrset-rdata dt span {
- display: inline-block;
- background-color: rgb(var(--color-hightlight-1));
- padding: 0.1em 0.5em;
- border-radius: 0.5em;
- margin-right: 0.1rem;
- font-size: .7rem;
-}
-
-.new-record form {
- width: auto;
-}
-
-.new-record form > div.form-row > * {
- flex-grow: 1;
-}
-
-.new-record form > div.form-row {
- display: flex;
- flex-wrap: wrap;
- gap: 2ch;
-}
-
-.new-record form label {
- margin-top: .25rem;
-}
-
-form div.input-group {
- display: flex;
- flex-direction: column;
-}
-
-form div.combined-input {
- display: flex;
-}
-
-form div.combined-input input {
- height: min-content;
- flex-grow: 1;
-}
-
-form div.combined-input span {
- font-size: .8rem;
- padding: .35rem;
- border: 1px solid rgb(var(--color-primary));;
- border-left: none;
- background: rgba(var(--color-hightlight-2),.2);
-}
-
-form.disabled {
- display: none;
-}
-
-.new-record form button,
-.new-record form input[type="submit"] {
- margin-right: 1ch;
- margin-top: .75rem;
-}
-
-.new-record header {
- margin-bottom: 0;
-}
-
-.new-record form .preview {
- margin: .5rem 0;
- border: 1px solid rgb(var(--color-primary));
-}
-
-.new-record form .preview p:first-of-type {
- margin-top: .5rem;
-}
-
-.new-record form .preview p:last-of-type {
- margin-bottom: .5rem;
-}
-
-.new-record form .preview p {
- display: flex;
-}
-
-.new-record form .preview code {
- padding: 0 .5rem;
- flex: 1;
-}
-
-.new-record form .preview img {
- padding: 0 .25rem;
- border-right: 1px solid #1b841b;
-}
-
-.new-record form .preview .addition {
- background: #d9fbd9;
-}
-
-.new-record form .preview h3 {
- margin: 0;
- padding: .0rem .5rem 0 .5rem;;
- font-size: 1rem;
- font-weight: normal;
- background: rgb(var(--color-primary));
- color: var(--color-contrast)
-}
diff --git a/src/dns/dns_driver.rs b/src/dns/dns_driver.rs
index 5f1181b..1a1da84 100644
--- a/src/dns/dns_driver.rs
+++ b/src/dns/dns_driver.rs
@@ -11,9 +11,8 @@ use domain::tsig::{Algorithm, Key, KeyName};
use domain::net::client::request::{self, RequestMessage, RequestMessageMulti, SendRequest, SendRequestMulti};
use tokio::net::TcpStream;
-use super::{rdata, record};
+use crate::ressouces::{rdata, record};
use super::{RecordDriver, ZoneDriver, DnsDriverError};
-use crate::errors::Error;
use async_trait::async_trait;
diff --git a/src/dns/mod.rs b/src/dns/mod.rs
index f00c618..624cac8 100644
--- a/src/dns/mod.rs
+++ b/src/dns/mod.rs
@@ -1,12 +1,13 @@
-pub mod rdata;
-pub mod record;
pub mod dns_driver;
use std::sync::Arc;
use async_trait::async_trait;
+use crate::ressouces::record;
+
pub type BoxedZoneDriver = Arc;
+pub type BoxedRecordDriver = Arc;
pub enum DnsDriverError {
ConnectionError { reason: Box },
OperationError { reason: Box },
diff --git a/src/dns/rdata.rs b/src/dns/rdata.rs
deleted file mode 100644
index 0ad5f67..0000000
--- a/src/dns/rdata.rs
+++ /dev/null
@@ -1,528 +0,0 @@
-use std::fmt::Write;
-use std::net::{Ipv4Addr, Ipv6Addr};
-
-use domain::base::rdata::ComposeRecordData;
-use domain::base::scan::Symbol;
-use domain::base::wire::{Composer, ParseError};
-use domain::base::{Name, ParseRecordData, ParsedName, RecordData, Rtype, ToName, Ttl};
-use domain::rdata;
-use domain::dep::octseq::{Parser, Octets};
-use serde::{Deserialize, Serialize};
-
-use crate::errors::Error;
-use crate::validation;
-
-use crate::macros::{append_errors, push_error};
-use super::record::RecordParseError;
-
-/// Type used to serialize / deserialize resource records data to response / request
-///
-#[derive(Debug, Deserialize, Serialize)]
-#[serde(tag = "type", content = "rdata")]
-#[serde(rename_all = "UPPERCASE")]
-pub enum RData {
- A(A),
- Aaaa(Aaaa),
- // TODO: CAA
- Cname(Cname),
- // TODO: DS
- Mx(Mx),
- Ns(Ns),
- Ptr(Ptr),
- Soa(Soa),
- Srv(Srv),
- // TODO: SSHFP
- // TODO: SVCB / HTTPS
- // TODO: TLSA
- Txt(Txt),
-}
-
-pub enum ParsedRData {
- A(rdata::A),
- Aaaa(rdata::Aaaa),
- Cname(rdata::Cname),
- Mx(rdata::Mx),
- Ns(rdata::Ns),
- Ptr(rdata::Ptr),
- Soa(rdata::Soa),
- Srv(rdata::Srv),
- Txt(rdata::Txt),
-}
-
-impl> From> for RData {
- fn from(value: ParsedRData) -> Self {
- match value {
- ParsedRData::A(record_rdata) => RData::A(record_rdata.into()),
- ParsedRData::Aaaa(record_rdata) => RData::Aaaa(record_rdata.into()),
- ParsedRData::Cname(record_rdata) => RData::Cname(record_rdata.into()),
- ParsedRData::Mx(record_rdata) => RData::Mx(record_rdata.into()),
- ParsedRData::Ns(record_rdata) => RData::Ns(record_rdata.into()),
- ParsedRData::Ptr(record_rdata) => RData::Ptr(record_rdata.into()),
- ParsedRData::Soa(record_rdata) => RData::Soa(record_rdata.into()),
- ParsedRData::Srv(record_rdata) => RData::Srv(record_rdata.into()),
- ParsedRData::Txt(record_rdata) => RData::Txt(record_rdata.into()),
- }
- }
-}
-
-impl TryFrom for ParsedRData>, Vec> {
- type Error = Vec;
-
- fn try_from(value: RData) -> Result {
- let rdata = match value {
- RData::A(record_rdata) => ParsedRData::A(record_rdata.parse_record()?),
- RData::Aaaa(record_rdata) => ParsedRData::Aaaa(record_rdata.parse_record()?),
- RData::Cname(record_rdata) => ParsedRData::Cname(record_rdata.parse_record()?),
- RData::Mx(record_rdata) => ParsedRData::Mx(record_rdata.parse_record()?),
- RData::Ns(record_rdata) => ParsedRData::Ns(record_rdata.parse_record()?),
- RData::Ptr(record_rdata) => ParsedRData::Ptr(record_rdata.parse_record()?),
- RData::Soa(record_rdata) => ParsedRData::Soa(record_rdata.parse_record()?),
- RData::Srv(record_rdata) => ParsedRData::Srv(record_rdata.parse_record()?),
- RData::Txt(record_rdata) => ParsedRData::Txt(record_rdata.parse_record()?),
- };
- Ok(rdata)
- }
-}
-
-
-
-macro_rules! parse_name {
- ($value:expr, $field:ident, $rtype:literal, $errors:expr) => {
- {
- let name = push_error!(
- validation::normalize_domain(&$value.$field),
- $errors, concat!("/", stringify!($field))
- );
-
- let name = name.and_then(|name| {
- push_error!(
- name.parse::>().map_err(|e| {
- Error::from(RecordParseError::RDataUnknown {
- input: $value.$field,
- field: stringify!(field).to_string(),
- rtype: $rtype.to_string(),
- }).with_cause(&e.to_string())
- }),
- $errors, concat!("/", stringify!($field))
- )
- });
-
- name
- }
- };
-}
-
-/* --------- A --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct A {
- pub address: String,
-}
-
-impl From for A {
- fn from(record_data: rdata::A) -> Self {
- A { address: record_data.addr().to_string() }
- }
-}
-
-impl A {
- pub fn parse_record(self) -> Result> {
- let mut errors = Vec::new();
-
- let address = push_error!(self.address.parse::().map_err(|e| {
- Error::from(RecordParseError::Ip4Address { input: self.address })
- .with_cause(&e.to_string())
- .with_path("/address")
- }), errors);
-
- if errors.is_empty() {
- Ok(rdata::A::new(address.unwrap()))
- } else {
- Err(errors)
- }
- }
-}
-
-/* --------- AAAA --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Aaaa {
- pub address: String,
-}
-
-impl From for Aaaa {
- fn from(record_data: rdata::Aaaa) -> Self {
- Aaaa { address: record_data.addr().to_string() }
- }
-}
-
-impl Aaaa {
- pub fn parse_record(self) -> Result> {
- let mut errors = Vec::new();
-
- let address = push_error!(self.address.parse::().map_err(|e| {
- Error::from(RecordParseError::Ip6Address { input: self.address })
- .with_cause(&e.to_string())
- .with_path("/address")
- }), errors);
-
- if errors.is_empty() {
- Ok(rdata::Aaaa::new(address.unwrap()))
- } else {
- Err(errors)
- }
- }
-}
-
-/* --------- CNAME --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Cname {
- pub target: String,
-}
-
-impl From> for Cname {
- fn from(record_data: rdata::Cname) -> Self {
- Cname { target: record_data.cname().to_string() }
- }
-}
-
-impl Cname {
- pub fn parse_record(self) -> Result>>, Vec> {
- let mut errors = Vec::new();
-
- let cname = parse_name!(self, target, "CNAME", errors);
-
- if errors.is_empty() {
- Ok(rdata::Cname::new(cname.unwrap()))
- } else {
- Err(errors)
- }
-
- }
-}
-
-/* --------- MX --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Mx {
- pub preference: u16,
- pub mail_exchanger: String,
-}
-
-impl From> for Mx {
- fn from(record_data: rdata::Mx) -> Self {
- Mx {
- preference: record_data.preference(),
- mail_exchanger: record_data.exchange().to_string()
- }
- }
-}
-
-impl Mx {
- fn parse_record(self) -> Result>>, Vec> {
- let mut errors = Vec::new();
-
- let mail_exchanger = parse_name!(self, mail_exchanger, "MX", errors);
-
- if errors.is_empty() {
- Ok(rdata::Mx::new(self.preference, mail_exchanger.unwrap()))
- } else {
- Err(errors)
- }
- }
-}
-
-/* --------- NS --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Ns {
- pub target: String,
-}
-
-impl From> for Ns {
- fn from(record_rdata: rdata::Ns) -> Self {
- Ns {
- target: record_rdata.nsdname().to_string(),
- }
- }
-}
-
-impl Ns {
- fn parse_record(self) -> Result>>, Vec> {
- let mut errors = Vec::new();
-
- let ns_name = parse_name!(self, target, "NS", errors);
-
- if errors.is_empty() {
- Ok(rdata::Ns::new(ns_name.unwrap()))
- } else {
- Err(errors)
- }
- }
-}
-
-/* --------- PTR --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Ptr {
- pub target: String,
-}
-
-impl From> for Ptr {
- fn from(record_rdata: rdata::Ptr) -> Self {
- Ptr {
- target: record_rdata.ptrdname().to_string(),
- }
- }
-}
-
-impl Ptr {
- fn parse_record(self) -> Result>>, Vec> {
- let mut errors = Vec::new();
-
- let ptr_name = parse_name!(self, target, "PTR", errors);
-
- if errors.is_empty() {
- Ok(rdata::Ptr::new(ptr_name.unwrap()))
- } else {
- Err(errors)
- }
- }
-}
-
-/* --------- SOA --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Soa {
- pub primary_server: String,
- pub maintainer: String,
- pub refresh: u32,
- pub retry: u32,
- pub expire: u32,
- pub minimum: u32,
- pub serial: u32,
-}
-
-impl From> for Soa {
- fn from(record_rdata: rdata::Soa) -> Self {
- Soa {
- primary_server: record_rdata.mname().to_string(),
- maintainer: record_rdata.rname().to_string(),
- refresh: record_rdata.refresh().as_secs(),
- retry: record_rdata.retry().as_secs(),
- expire: record_rdata.expire().as_secs(),
- minimum: record_rdata.minimum().as_secs(),
- serial: record_rdata.serial().into(),
- }
- }
-}
-
-impl Soa {
- fn parse_record(self) -> Result>>, Vec> {
- let mut errors = Vec::new();
-
- let primary_ns = parse_name!(self, primary_server, "SOA", errors);
- let maintainer = parse_name!(self, maintainer, "SOA", errors);
-
- if errors.is_empty() {
- Ok(rdata::Soa::new(
- primary_ns.unwrap(),
- maintainer.unwrap(),
- self.refresh.into(),
- Ttl::from_secs(self.retry),
- Ttl::from_secs(self.expire),
- Ttl::from_secs(self.minimum),
- Ttl::from_secs(self.serial),
- ))
- } else {
- Err(errors)
- }
- }
-}
-
-/* --------- SRV --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Srv {
- pub server: String,
- pub port: u16,
- pub priority: u16,
- pub weight: u16,
-}
-
-impl From> for Srv {
- fn from(record_data: rdata::Srv) -> Self {
- Srv {
- server: record_data.target().to_string(),
- priority: record_data.priority(),
- weight: record_data.weight(),
- port: record_data.port(),
- }
- }
-}
-
-impl Srv {
- fn parse_record(self) -> Result>>, Vec> {
- let mut errors = Vec::new();
-
- let server = parse_name!(self, server, "SRV", errors);
-
- if errors.is_empty() {
- Ok(rdata::Srv::new(
- self.priority,
- self.weight,
- self.port,
- server.unwrap(),
- ))
- } else {
- Err(errors)
- }
- }
-}
-
-
-/* --------- TXT --------- */
-
-#[derive(Debug, Deserialize, Serialize)]
-pub struct Txt {
- pub text: String,
-}
-
-impl> From> for Txt {
- fn from(record_data: rdata::Txt) -> Self {
- let mut concatenated_text = String::new();
- for text in record_data.iter() {
- for c in text {
- // Escapes '\' and non printable chars
- let c = Symbol::display_from_octet(*c);
- write!(concatenated_text, "{}", c).unwrap();
- }
- }
-
- Txt {
- text: concatenated_text
- }
- }
-}
-
-impl Txt {
- fn parse_record(self) -> Result>, Vec> {
- let mut errors = Vec::new();
- let data = append_errors!(validation::parse_txt_data(&self.text), errors, "/text");
- let data = data.and_then(|data| {
- push_error!(rdata::Txt::build_from_slice(&data).map_err(|e| {
- Error::from(RecordParseError::RDataUnknown {
- input: self.text,
- field: "text".into(),
- rtype: "TXT".into(),
- }).with_cause(&e.to_string())
- .with_path("/text")
- }), errors)
- });
-
-
-
- if errors.is_empty() {
- Ok(data.unwrap())
- } else {
- Err(errors)
- }
- }
-}
-
-/* --------- ParsedRData: domain traits impl --------- */
-
-impl ParsedRData {
- pub fn rtype(&self) -> Rtype {
- match self {
- ParsedRData::A(_) => Rtype::A,
- ParsedRData::Aaaa(_) => Rtype::AAAA,
- ParsedRData::Cname(_) => Rtype::CNAME,
- ParsedRData::Mx(_) => Rtype::MX,
- ParsedRData::Ns(_) => Rtype::NS,
- ParsedRData::Ptr(_) => Rtype::PTR,
- ParsedRData::Soa(_) => Rtype::SOA,
- ParsedRData::Srv(_) => Rtype::SRV,
- ParsedRData::Txt(_) => Rtype::TXT,
- }
- }
-}
-
-impl RecordData for ParsedRData {
- fn rtype(&self) -> Rtype {
- ParsedRData::rtype(self)
- }
-}
-
-impl<'a, Octs: Octets + ?Sized> ParseRecordData<'a, Octs> for ParsedRData>, Octs::Range<'a>> {
- fn parse_rdata(
- rtype: Rtype,
- parser: &mut Parser<'a, Octs>,
- ) -> Result