diff --git a/public/swagger/swagger.html b/public/swagger/swagger.html
index 1952a4a..b64f8cc 100644
--- a/public/swagger/swagger.html
+++ b/public/swagger/swagger.html
@@ -39,8 +39,7 @@
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
- //url: "https://petstore.swagger.io/v2/swagger.json",
- url: "./swagger.yaml",
+ url: "./v1/swagger.yaml",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
diff --git a/public/swagger/swagger-files.yaml b/public/swagger/v0/swagger-files.yaml
similarity index 100%
rename from public/swagger/swagger-files.yaml
rename to public/swagger/v0/swagger-files.yaml
diff --git a/public/swagger/swagger-port.yaml b/public/swagger/v0/swagger-port.yaml
similarity index 100%
rename from public/swagger/swagger-port.yaml
rename to public/swagger/v0/swagger-port.yaml
diff --git a/public/swagger/swagger-register.yaml b/public/swagger/v0/swagger-register.yaml
similarity index 100%
rename from public/swagger/swagger-register.yaml
rename to public/swagger/v0/swagger-register.yaml
diff --git a/public/swagger/swagger-who.yaml b/public/swagger/v0/swagger-who.yaml
similarity index 100%
rename from public/swagger/swagger-who.yaml
rename to public/swagger/v0/swagger-who.yaml
diff --git a/public/swagger/swagger.yaml b/public/swagger/v0/swagger.yaml
similarity index 100%
rename from public/swagger/swagger.yaml
rename to public/swagger/v0/swagger.yaml
diff --git a/public/swagger/v1/files.yaml b/public/swagger/v1/files.yaml
new file mode 100644
index 0000000..ef3e997
--- /dev/null
+++ b/public/swagger/v1/files.yaml
@@ -0,0 +1,40 @@
+paths:
+ summary: "CRUD operations for namespace scoped hosted files"
+ get:
+ tags:
+ - files
+ parameters:
+ - $ref: "#/components/parameters/token"
+ - $ref: "#/components/parameters/path"
+ post:
+ tags:
+ - files
+ parameters:
+ - $ref: "#/components/parameters/token"
+ - $ref: "#/components/parameters/path"
+ requestBody:
+ $ref: "#/components/schemas/requestForm"
+ put:
+ tags:
+ - files
+ parameters:
+ - $ref: "#/components/parameters/token"
+ - $ref: "#/components/parameters/path"
+ requestBody:
+ $ref: "#/components/schemas/requestForm"
+ delete:
+ tags:
+ - files
+ parameters:
+ - $ref: "#/components/parameters/token"
+ - $ref: "#/components/parameters/path"
+
+components:
+ parameters:
+ token:
+ $ref: "./swagger.yaml#/components/parameters/token"
+ path:
+ $ref: "./swagger.yaml#/components/parameters/path"
+ schemas:
+ requestForm:
+ $ref: "./swagger.yaml#/components/schemas/requestForm"
diff --git a/public/swagger/v1/swagger.yaml b/public/swagger/v1/swagger.yaml
new file mode 100644
index 0000000..15c15dc
--- /dev/null
+++ b/public/swagger/v1/swagger.yaml
@@ -0,0 +1,187 @@
+openapi: 3.0.2
+info:
+ title: DnDex
+ description: |
+ DnDex API, pronounced dee-IN-dex
+
+ UI via htp://ui.dndex.lan:8080/, API via http://api.dndex.lan:8080/
+
+ Sources
+ * OpenAPI
+ * Swagger UI
+ version: 0.1.0
+
+servers:
+- url: http://api.dndex.lan:8080/
+- url: http://authapi.dndex.lan:8080/
+
+paths:
+ /version:
+ $ref: "./version.yaml#/paths"
+ /files/{path}:
+ $ref: "./files.yaml#/paths"
+ /users/register:
+ $ref: "./users/register.yaml#/paths"
+ /users/login:
+ $ref: "./users/login.yaml#/paths"
+ #/entities:
+ # $ref: "./entities.yaml#/paths"
+
+components:
+ parameters:
+ path:
+ name: path
+ in: path
+ required: true
+ schema:
+ type: string
+
+ token:
+ name: DnDex-Auth
+ in: cookie
+ required: true
+ schema:
+ type: string
+
+ schemas:
+ responseOK:
+ content:
+ application/json:
+ properties:
+ ok:
+ type: boolean
+ example: true
+
+ requestForm:
+ content:
+ application/x-www-form-urlencoded:
+ schema:
+ type: string
+ example: http://imgur.com/big-tiddy-goth-gf.jpg
+
+ objectID:
+ title: "one ID"
+ type: string
+ example: "abc-123-def-456"
+
+ objectOne:
+ title: "one entity"
+ type: object
+ properties:
+ _id:
+ $ref: "/components/schemas/objectID"
+ name:
+ type: string
+ example: "Jeff Snow"
+ type:
+ type: string
+ example: "doggo"
+ title:
+ type: string
+ example: "Meme Lord"
+ text:
+ type: string
+ example: "Lorem ipsum"
+ modified:
+ type: int
+ example: 8675309
+ attachments:
+ type: object
+ additionalProperties:
+ type: object
+ properties:
+ location:
+ type: string
+ example: "/files/my/file.txt"
+ connections:
+ type: object
+ additionalProperties:
+ type: object
+ properties:
+ relationship:
+ type: string
+ example: "friendly"
+
+ securitySchemes:
+ token:
+ name: DnDex-Auth
+ in: cookie
+ type: apiKey
+ description: |
+ Disabled by default but required by all endpoints when enabled
+
+ Provided as AES-GCM 12-byte-padded ciphertext on all unauthorized requests via a response to a `/users/login` request.
+
+
+
+ [Code example of decrypting a token in Javascript](https://notes-server.remote.blapointe.com/notes/disciplines/tech/languages/Encryption.md#toc_1)
+
+ ```javascript
+ class NewAuthToken {
+ constructor(key) {
+ if (!key) {
+ throw "invalid key"
+ }
+ this.key = key.repeat(32).substr(0, 32)
+ }
+
+ decode(b64, callback) {
+ var ciphertext = this.base64_decode(b64)
+
+ var iv = ciphertext.substr(0, 12)
+ var encrypted = ciphertext.substr(iv.length, ciphertext.length-iv.length)
+
+ this.get_crypto_key()
+ .then(function(crypto_key) {
+ NewAuthToken.decrypt(crypto_key, iv, encrypted, callback)
+ })
+ }
+
+ base64_decode(b64) {
+ return atob(b64)
+ }
+
+ static to_buffer(s) {
+ var bytes = new Uint8Array(s.length)
+ for (var i = 0; i < s.length; i++) {
+ bytes[i] = s.charCodeAt(i)
+ }
+ return bytes.buffer
+ }
+
+ static decrypt(crypto_key, iv, encrypted, callback) {
+ window.crypto.subtle.decrypt(
+ {name: "AES-GCM", iv: NewAuthToken.to_buffer(iv)},
+ crypto_key,
+ NewAuthToken.to_buffer(encrypted),
+ )
+ .then(function(decrypted) {
+ callback(String.fromCharCode.apply(null, new Uint8Array(decrypted)))
+ })
+ }
+
+ get_crypto_key() {
+ return crypto.subtle.importKey(
+ "raw",
+ NewAuthToken.to_buffer(this.key),
+ "AES-GCM",
+ false,
+ ["decrypt"]
+ )
+ }
+
+ set_token(encoded_token) {
+ this.decode(encoded_token, function (token) {
+ console.log("Set-Cookie DnDex-Auth="+token)
+ document.cookie = "DnDex-Auth=" + token + ";path=/"
+ })
+ }
+ }
+
+ authtoken = new NewAuthToken("123").set_token("SOY05yF/9iv3YG71sKkQPVaEwO53PCX8qZhDHS9JUohBgVl5Qr9/GTKK/TJ6OozhHN7QBIGmHNzQxTRRSLs4Lw==")
+ ```
+
+
+security:
+- {}
+- token: []
diff --git a/public/swagger/v1/users/login.yaml b/public/swagger/v1/users/login.yaml
new file mode 100644
index 0000000..e7473e5
--- /dev/null
+++ b/public/swagger/v1/users/login.yaml
@@ -0,0 +1,15 @@
+paths:
+ summary: "Log in to namespaces"
+ post:
+ description: "Get an encrypted token and its salt as described in the security section"
+ tags:
+ - users
+ requestBody:
+ content:
+ application/x-www-form-urlencoded:
+ schema:
+ type: object
+ properties:
+ DnDex-User:
+ type: string
+ example: "namespace"
diff --git a/public/swagger/v1/users/register.yaml b/public/swagger/v1/users/register.yaml
new file mode 100644
index 0000000..6046c7b
--- /dev/null
+++ b/public/swagger/v1/users/register.yaml
@@ -0,0 +1,17 @@
+paths:
+ summary: "Registering namespaces"
+ post:
+ tags:
+ - users
+ requestBody:
+ content:
+ application/x-www-form-urlencoded:
+ schema:
+ type: object
+ properties:
+ DnDex-User:
+ type: string
+ example: "namespace"
+ DnDex-Auth:
+ type: string
+ example: "password"
diff --git a/public/swagger/v1/version.yaml b/public/swagger/v1/version.yaml
new file mode 100644
index 0000000..c2de714
--- /dev/null
+++ b/public/swagger/v1/version.yaml
@@ -0,0 +1,15 @@
+paths:
+ get:
+ tags:
+ - version
+ summary: "Get the running server version"
+ responses:
+ 200:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ version:
+ type: string
+ example: "02c5d795cf631a33528234a9cf52907c6cd34834"