# IcyDNS HTTP API HTTP API for managing BIND zone files. ## Running This application is intended to be run behind a proxy. Requires node v14+ for `fs/promises`. Also requires `bind-tools` for checking zone files. - `npm install` - `npm run build` - `npm start` ### Environment variables - `PORT` - server port - `ZONEFILES` - path to zone files - `CACHE_TTL` - internal zone cache time-to-live - `LOG_DIR` - Logs directory - `LOG_FILES` - Log to files (boolean) - `RNDC_SERVER` - RNDC host - `RNDC_PORT` - RNDC port - `RNDC_KEYFILE` - location of RNDC's key file Zones are automatically reloaded using `rndc` after updates. If you do not have rndc configured, you will need to reload the zones manually, but the files still get updated. ## API **All requests are prefixed with `/api/v1`.** Authorization is by bearer token, i.e. `-H 'Authorization: Bearer '`. `?` denotes optional parameter. ### `GET /zone/{domain}` Returns all of `{domain}`'s DNS records. **Query:** None **Response:** ```typescript { ttl: number; records: [ [index]: { name: string; type: string; value: string; } ] } ``` ### `GET /zone/{domain}/download` Provides `{domain}`'s records as a file. **Query:** None **Response:** BIND zone file ### `POST /zone/{domain}` Reloads `{domain}`'s zone file. Optionally changes the zone file's TTL value. **Body:** ```typescript { ttl?: number; } ``` **Response:** ```typescript { success: boolean; message: string; ttl?: number; } ``` ### `GET /zone/records/{domain}` Returns all of `{domain}`'s DNS records or performs a search based on provided query parameters. **Query:** - `name?` - `type?` - `value?` **Response:** ```typescript [ [index]: { name: string; type: string; value: string; index?: number; // when searching only } ] ``` ### `PATCH /zone/records/{domain}` Updates or marks for deletion a single or multiple DNS records of `{domain}` at `index`. **Warning:** `setIndex` will cause your other records to shift around, so it is currently only recommended to use for a single record at a time. **Body:** ```typescript { record: { index: number; name?: string; type?: string; value?: string; setIndex?: number; forDeletion?: boolean; } | {...}[]; } ``` **Response:** ```typescript { success: boolean; message: string; changed: DNSRecord[]; errors: { message: string; record: DNSRecord; }[]; } ``` ### `POST /zone/records/{domain}` Creates a single or multiple new DNS records for `{domain}`. **Body:** ```typescript { record: { name: string; type: string; value: string; index?: number; // insert at this exact index (not after this index, at it!) } | {...}[]; } ``` **Response:** ```typescript { success: boolean; message: string; created: ({ index: number, ...DNSRecord })[]; errors: { message: string; record: DNSRecord; }[]; } ``` ### `DELETE /zone/records/{domain}` Deletes a single or multiple DNS records from `{domain}` at `index`. **Warning:** Deleting an index that is not at the end of the record causes following records' indexes to shift back by one. Refresh your indexes after every addition and deletion! **Body:** ```typescript { index: number | number[]; } ``` **Response:** ```typescript { success: boolean; message: string; deleted: DNSRecord[]; errors: { message: string; record: DNSRecord; }[]; } ``` ### `POST /set-ip/{domain}` Quickly updates the `{domain}`'s IP address (first occurences of `A` and `AAAA` records of `@` or `subdomain`). One of the IP addresses is taken from the request, so it's a good idea to use curl with `-4` to automatically set the IPv4 address and provide the IPv6 address with a body parameter. **Body:** ```typescript { ipv4?: string; ipv6?: string; subdomain?: string; dualRequest?: boolean; } ``` **Response:** ```typescript { success: boolean; message: string; actions: string[]; // detailed descriptions of what was actually done } ```