diff --git a/documentation/api-documentation.yml b/documentation/api-documentation.yml index ca54e85..106bea9 100644 --- a/documentation/api-documentation.yml +++ b/documentation/api-documentation.yml @@ -1602,927 +1602,6 @@ paths: message: "You are blacklisted from accessing this resource" security: - APIToken: [] - /token/create: - post: - operationId: "CreateToken" - description: |- - Creates a token using the provided information. - Returns the token information if successful, otherwise returns an error. - - Permissions Required: `Global::Token.Create` - summary: "Create a Token" - requestBody: - description: "The new token information" - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/TokenCreationRequestBody" - example: - value: - firebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - responses: - 201: - description: "The information on the generated token" - content: - application/json: - schema: - $ref: "#/components/schemas/TokenCreationResponse" - examples: - token: - summary: "Created Token Data" - value: - token: "fjkh_fdasABc12.dshfa34287y_FDAS34_2" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested information" - 500: - description: "Unable to create token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 19 - message: "Unable to create requested token" - security: - - APIToken: [] - /token/delete: - delete: - operationId: "DeleteToken" - description: |- - Deletes the given token. - Returns `true` if successful, otherwise returns an error. - - Permissions Required: `Global::Token.Delete` - summary: "Delete Token" - parameters: - - in: "query" - name: "token" - description: "The token to delete" - schema: - type: string - example: 'afsdjahfljdfhajfkel_fhealufu342_o7ffff7bfew7ofbew.fkdahljekfhuahjfuaeu_awfefudfayvi' - responses: - 200: - description: "The successful notification of the deletion" - content: - application/json: - schema: - $ref: "#/components/schemas/TokenDeletionResponse" - examples: - deleted: - value: - message: "Token deleted successfully" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested information" - 500: - description: "Unable to delete token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 21 - message: "Unable to delete requested token" - security: - - APIToken: [] - /token/list: - get: - operationId: "ListTokens" - description: |- - Lists all API keys along with the information associated with it. - Returns the list of tokens if successful, otherwise returns an error. - - Permissions Required: `Global::Token.ReadAll` - summary: "List Tokens" - responses: - 200: - description: "The list of tokens" - content: - application/json: - schema: - $ref: "#/components/schemas/ListTokenResponse" - examples: - tokens: - value: - - license: "1234-5678-9012-3456" - token: "fjkh_fdasABc12.dshfa34287y_FDAS34_2" - associatedfirebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - username: "JohnDoe0001" - - license: "1234-5678-9012-3456" - token: "fjkh_fdasABc12.dshfa34287y_FDAS34_2" - associatedfirebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - username: "JohnDoe0001" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - security: - - APIToken: [] - /token/info: - get: - operationId: "GetTokenInfo" - description: |- - Gets the token information for the given token. - Returns the token information if the token exists, otherwise returns an error. - - Permissions Required: `Global::Token.Read` - summary: "Get Token Info" - parameters: - - in: "query" - name: "token" - description: "The token to get information for" - schema: - type: string - example: "fjkh_fdasABc12.dshfa34287y_FDAS34_2" - responses: - 200: - description: "The token information for the given token" - content: - application/json: - schema: - $ref: "#/components/schemas/TokenData" - examples: - token: - value: - license: "1234-5678-9012-3456" - token: "fjkh_fdasABc12.dshfa34287y_FDAS34_2" - associatedfirebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - username: "JohnDoe0001" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested information" - 500: - description: "Unable to get token information" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 0 - message: "An unknown error occurred" - security: - - APIToken: [] - /user/get: - get: - operationId: "GetUser" - description: |- - Gets the user information for the user with the given ID. - Returns the user information if the user exists, otherwise returns an error. - - Permissions Required: `Global::User.Read` unless requesting own information" - summary: "Get User Info by ID" - parameters: - - in: "header" - name: "x-uid" - description: "The Firebase UID of the user to get information for" - schema: - type: string - example: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - responses: - 200: - description: "The user information for the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/GetUserInfoResponse" - examples: - user: - summary: "Example User" - value: - id: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - username: "JohnDoe0001" - fullName: "John Doe" - email: "example@example.com" - permissions: 0 - 400: - description: "Missing user information" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-User: - summary: "Missing UID Header" - value: - code: 8 - message: "Missing Header Parameter(s)" - Invalid-User: - summary: "Invalid UID Header" - value: - code: 9 - message: "Invalid Header Parameter(s)" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested information" - security: - - APIToken: [] - /user/update: - patch: - operationId: "UpdateUser" - description: |- - Updates the user information for the user with the given ID. - Returns the user information if the user exists, otherwise returns an error. - - Permissions Required: `Global::User.Write` unless updating own user information with few field exceptions - summary: "Update User Info by ID" - parameters: - - in: "header" - name: "x-uid" - description: "The Firebase UID of the user to get information for" - schema: - type: string - example: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - requestBody: - description: "The new user information" - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/UpdateUserInfo" - examples: - displayname: - value: - displayname: "newDisplayName" - email: - value: - email: "newEmail@example.com" - password: - value: - password: "newPassword" - perms: - value: - perms: "0:0:1;0:0:2" - responses: - 200: - description: "Successful Response" - content: - application/json: - schema: - $ref: "#/components/schemas/UpdateUserInfoResponse" - examples: - displayname: - summary: "Update Response for Display Name" - value: - id: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - updatedUser: - id: 19 - firebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - firstname: "John" - lastname: "Doe" - displayname: "newDisplayName" - email: "example@example.com" - dateofbirth: "2000-01-01" - permissions: 0 - betaAccess: 0 - email: - summary: "Update Response for Email" - value: - id: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - updatedUser: - id: 19 - firebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - firstname: "John" - lastname: "Doe" - displayname: "JohnDoe0001" - email: "newEmail@example.com" - dateofbirth: "2000-01-01" - permissions: 0 - betaAccess: 0 - password: - summary: "Update Response for Password" - value: - id: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - updatedUser: - id: 19 - firebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - firstname: "John" - lastname: "Doe" - displayname: "JohnDoe0001" - email: "example@example.com" - dateofbirth: "2000-01-01" - permissions: 0 - betaAccess: 0 - perms: - summary: "Update Response for Permissions" - value: - id: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - updatedUser: - id: 19 - firebaseuid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - firstname: "John" - lastname: "Doe" - displayname: "JohnDoe0001" - email: "example@example.com" - dateofbirth: "2000-01-01" - permissions: 0 - betaAccess: 1 - 400: - description: "Missing user information" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-User: - summary: "Missing UID Header" - value: - code: 8 - message: "Missing Header Parameter(s)" - Invalid-User: - summary: "Invalid UID Header" - value: - code: 9 - message: "Invalid Header Parameter(s)" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested resource" - 500: - description: "Unable to update user" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 16 - message: "Unable to update user" - security: - - APIToken: [] - /user/create: - post: - operationId: "CreateUser" - description: |- - Creates a user using the provided information. - Returns the user information if successful, otherwise returns an error. - - Permissions Required: `Global::User.Create` - summary: "Create a User" - requestBody: - description: "The new user information" - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/CreateUserInfo" - example: - value: - username: "JohnDoe0001" - firstname: "John" - lastname: "Doe" - email: "example@example.com" - password: "ARandomPassword" - responses: - 201: - description: "The user information for the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/CreateUserInfoResponse" - examples: - user: - summary: "Example User" - value: - user: - uid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - email: "example@example.com" - emailVerified: false - displayName: "JohnDoe0001" - disabled: false - metadata: - lastSignInTime: "null" - creationTime: "Sat, 23 Sep 2023 16:06:10 GMT" - lastRefreshTime: "null" - tokensValidAfterTime: "Sat, 23 Sep 2023 16:06:10 GMT" - providerData: - - uid: "example@example.com" - displayName: "JohnDoe0001" - email: "example@example.com" - providerId: "password" - username: "JohnDoe0001" - fullName: "John Doe" - email: "example@example.com" - permissions: 0 - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested information" - 500: - description: "Unable to create user" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 15 - message: "Unable to create user" - security: - - APIToken: [] - /user/delete: - delete: - operationId: "DeleteUser" - description: |- - Deletes the user with the given ID. - Returns `true if successful, otherwise returns an error. - - Permissions Required: `Global::User.Delete` - summary: "Delete User by ID" - parameters: - - in: "header" - name: "x-uid" - description: "The Firebase UID of the user to get delete" - schema: - type: string - example: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - responses: - 200: - description: "The successful notification of the deletion" - content: - application/json: - schema: - $ref: "#/components/schemas/DeleteUserInfoResponse" - examples: - deleted: - summary: "User Deleted" - value: - uid: "gPcqw6MAbXbZs6ARohHqT2vapFY2" - deleted: true - 400: - description: "Missing user information" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-User: - summary: "Missing UID Header" - value: - code: 8 - message: "Missing Header Parameter(s)" - Invalid-User: - summary: "Invalid UID Header" - value: - code: 9 - message: "Invalid Header Parameter(s)" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested resource" - 500: - description: "Error with the given ID" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 17 - message: "Unable to delete requested user" - security: - - APIToken: [] - /weather/current: - get: - operationId: "GetCurrentWeather" - description: |- - Gets the current weather for the given location. - Returns the weather if successful, otherwise returns an error. - - Permissions Required: `Weather::Current` - summary: "Get Current Weather" - parameters: - - in: "header" - name: "x-city" - example: "Washington D.C." - description: "The city to get the weather for" - schema: - type: string - - in: "header" - name: "x-coords" - description: "The coordinates to get the weather for" - example: "38.8976633,-77.0365739" - schema: - type: string - responses: - 200: - description: "The weather for the given location" - content: - application/json: - schema: - $ref: "#/components/schemas/WeatherCurrentData" - examples: - WashingtonDC: - value: - coord: - lon: -77.0369 - lat: 38.9072 - weather: - - id: 803 - main: "Clouds" - description: "broken clouds" - icon: "04d" - base: "stations" - main: - temp: 63.32 - feels_like: 62.83 - temp_min: 60.82 - temp_max: 66.13 - pressure: 1026 - humidity: 74 - visibility: 10000 - wind: - speed: 11.5 - deg: 20 - clouds: - all: 75 - dt: 1695829210 - sys: - type: 2 - id: 2084333 - country: "US" - sunrise: 1695812403 - sunset: 1695855499 - timezone: -14400 - id: 4140963 - name: "Washington D.C." - cod: 200 - 400: - description: "Missing location information" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Location: - value: - code: 8 - message: "Missing Header Parameter(s)" - Invalid-Location: - value: - code: 9 - message: "Invalid Header Parameter(s)" - 401: - description: "Invalid/Missing API Token" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Token: - summary: "Missing API Token" - value: - code: 3 - message: "No API key provided" - Invalid-Token: - summary: "Invalid API Token" - value: - code: 4 - message: "Invalid API key provided" - 403: - description: "Missing Permissions" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - Missing-Permissions: - value: - code: 1 - message: "You are not authorized to access this resource" - Blacklisted: - value: - code: 2 - message: "You are blacklisted from accessing this resource" - 404: - description: "Error with the given location" - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorData" - examples: - error: - value: - code: 22 - message: "Unable to retreive requested information" - security: - - APIToken: [] /whois/dns: get: operationId: "GetDNSWhois" diff --git a/modules/api/crypto.js b/modules/api/crypto.js deleted file mode 100644 index e69de29..0000000 diff --git a/modules/api/facts.js b/modules/api/facts.js deleted file mode 100644 index e69de29..0000000 diff --git a/modules/api/location.js b/modules/api/location.js index e69de29..fb7775d 100644 --- a/modules/api/location.js +++ b/modules/api/location.js @@ -0,0 +1,52 @@ +const xml = require('xml'); +const yaml = require('yaml'); + +class Location { + constructor(data) { + this.address = { + full: data.address.full || '', + houseNumber: data.address.houseNumber || '', + street: data.address.street || '', + city: data.address.city || '', + region: data.address.region || '', + country: data.address.country || '', + postalCode: data.address.postalCode || '', + }; + this.pluscode = data.pluscode || ''; + this.coords = { + lat: data.coords.lat || 0, + lng: data.coords.lng || 0, + }; + } + get JSON() { + return JSON.stringify({ + address: this.address, + pluscode: this.pluscode, + coords: this.coords, + }); + } + get XML() { + return xml({ + address: [ + { full: this.address.full }, + { houseNumber: this.address.houseNumber }, + { street: this.address.street }, + { city: this.address.city }, + { region: this.address.region }, + { country: this.address.country }, + { postalCode: this.address.postalCode }, + ], + pluscode: this.pluscode, + coords: this.coords, + }); + } + get YAML() { + return yaml.stringify({ + address: this.address, + pluscode: this.pluscode, + coords: this.coords, + }); + } +} + +module.exports = Location; diff --git a/modules/api/phone.js b/modules/api/phone.js index e69de29..3fb8365 100644 --- a/modules/api/phone.js +++ b/modules/api/phone.js @@ -0,0 +1,69 @@ +const xml = require('xml'); +const yaml = require('yaml'); + +class Phone { + constructor(data) { + this.status = data.status || 'error'; + this.phone = data.phone || ''; + this.phoneValid = data.phone_valid || false; + this.phoneType = data.phone_type || ''; + this.phoneRegion = data.phone_region || ''; + this.country = data.country || ''; + this.countryCode = data.country_code || ''; + this.countryPrefix = data.country_prefix || ''; + this.internationalNumber = data.international_number || ''; + this.localNumber = data.local_number || ''; + this.e164 = data.e164 || ''; + this.carrier = data.carrier || ''; + } + get JSON() { + return JSON.stringify({ + status: this.status, + phone: this.phone, + phoneValid: this.phoneValid, + phoneType: this.phoneType, + phoneRegion: this.phoneRegion, + country: this.country, + countryCode: this.countryCode, + countryPrefix: this.countryPrefix, + internationalNumber: this.internationalNumber, + localNumber: this.localNumber, + e164: this.e164, + carrier: this.carrier, + }); + } + get XML() { + return xml({ + status: this.status, + phone: this.phone, + phoneValid: this.phoneValid, + phoneType: this.phoneType, + phoneRegion: this.phoneRegion, + country: this.country, + countryCode: this.countryCode, + countryPrefix: this.countryPrefix, + internationalNumber: this.internationalNumber, + localNumber: this.localNumber, + e164: this.e164, + carrier: this.carrier, + }); + } + get YAML() { + return yaml.stringify({ + status: this.status, + phone: this.phone, + phoneValid: this.phoneValid, + phoneType: this.phoneType, + phoneRegion: this.phoneRegion, + country: this.country, + countryCode: this.countryCode, + countryPrefix: this.countryPrefix, + internationalNumber: this.internationalNumber, + localNumber: this.localNumber, + e164: this.e164, + carrier: this.carrier, + }); + } +} + +module.exports = Phone; diff --git a/modules/api/quote.js b/modules/api/quote.js index e69de29..d06c642 100644 --- a/modules/api/quote.js +++ b/modules/api/quote.js @@ -0,0 +1,33 @@ +const xml = require('xml'); +const yaml = require('yaml'); + +class Quote { + constructor(data) { + this.quotes = data.quote; + this.author = data.author; + this.tags = data.tags; + } + get JSON() { + return JSON.stringify({ + quotes: this.quotes, + author: this.author, + tags: this.tags, + }); + } + get XML() { + return xml({ + quotes: this.quotes, + author: this.author, + tags: this.tags, + }); + } + get YAML() { + return yaml.stringify({ + quotes: this.quotes, + author: this.author, + tags: this.tags, + }); + } +} + +module.exports = Quote; diff --git a/modules/api/token.js b/modules/api/token.js deleted file mode 100644 index e69de29..0000000 diff --git a/modules/api/user.js b/modules/api/user.js deleted file mode 100644 index e69de29..0000000 diff --git a/modules/api/weather.js b/modules/api/weather.js deleted file mode 100644 index e69de29..0000000 diff --git a/modules/api/whois.js b/modules/api/whois.js index e69de29..904fa41 100644 --- a/modules/api/whois.js +++ b/modules/api/whois.js @@ -0,0 +1,192 @@ +/* eslint-disable id-length */ +const xml = require('xml'); +const yaml = require('yaml'); + +class Contact { + constructor(data) { + this.name = data.name || 'Unknown'; + this.organization = data.organization || 'Unknown'; + this.street = data.street || 'Unknown'; + this.city = data.city || 'Unknown'; + this.state = data.state || 'Unknown'; + this.postalCode = data.postalCode || 'Unknown'; + this.country = data.country || 'Unknown'; + this.phone = data.phone || 'Unknown'; + this.fax = data.fax || 'Unknown'; + this.email = data.email || 'Unknown'; + } + get JSON() { + return { + name: this.name, + organization: this.organization, + street: this.street, + city: this.city, + state: this.state, + postalCode: this.postalCode, + country: this.country, + phone: this.phone, + fax: this.fax, + email: this.email, + }; + } + get XML() { + return [ + { name: this.name }, + { organization: this.organization }, + { street: this.street }, + { city: this.city }, + { state: this.state }, + { postalCode: this.postalCode }, + { country: this.country }, + { phone: this.phone }, + { fax: this.fax }, + { email: this.email }, + ]; + } +} + + + +class DNS { + constructor(data) { + this.SOA = data.SOA || {}; + this.A = data.A || ''; + this.CAA = data.CAA || []; + this.CNAME = data.CNAME || ''; + this.SRV = data.SRV || []; + this.AAAA = data.AAAA || ''; + this.PTR = data.PTR || []; + this.TXT = data.TXT || []; + this.NS = data.NS || []; + this.MX = data.MX || []; + } + get JSON() { + return { + SOA: this.SOA, + A: this.A, + CAA: this.CAA, + CNAME: this.CNAME, + SRV: this.SRV, + AAAA: this.AAAA, + PTR: this.PTR, + TXT: this.TXT, + NS: this.NS, + MX: this.MX, + }; + } + get XML() { + return xml(this.XMLData); + } + get XMLData() { + return [ + { + SOA: [ + { nsname: this.SOA.nsname }, + { serial: this.SOA.serial }, + { expire: this.SOA.expire }, + { minttl: this.SOA.minttl }, + { retry: this.SOA.retry }, + { refresh: this.SOA.refresh }, + { hostmaster: this.SOA.hostmaster }, + ], + }, + { A: this.A }, + { + CAA: this.CAA.map(rec => ( + rec.iodef + ? { iodef: rec.iodef } + : { main: rec.main, wild: rec.wild, issuer: rec.issuer } + )), + }, + { CNAME: this.CNAME }, + { SRV: this.SRV.map(rec => ({ record: rec })) }, + { AAAA: this.AAAA }, + { PTR: this.PTR.map(rec => ({ record: rec })) }, + { TXT: this.TXT.map(rec => ({ record: rec })) }, + { NS: this.NS.map(rec => ({ record: rec })) }, + { MX: this.MX.map(rec => ({ priority: rec.priority, exchange: rec.exchange })) }, + ]; + } + get YAML() { + return yaml.stringify(this.JSON); + } +} + +class WHOIS { + constructor(data) { + this.expirationDate = data.expirationDate || 'Unknown'; + this.billing = new Contact(data.billing); + this.registrar = data.registrar || 'Unknown'; + this.admin = new Contact(data.admin); + this.domainName = data.domainName || 'Unknown'; + this.creationDate = data.creationDate || 'Unknown'; + this.tech = new Contact(data.tech); + this.updatedDate = data.updatedDate || 'Unknown'; + this.registrant = new Contact(data.registrant); + this.status = data.status || []; + } + get JSON() { + return { + expirationDate: this.expirationDate, + billing: this.billing.JSON, + registrar: this.registrar, + admin: this.admin.JSON, + domainName: this.domainName, + creationDate: this.creationDate, + tech: this.tech.JSON, + updatedDate: this.updatedDate, + registrant: this.registrant.JSON, + status: this.status, + }; + } + get XML() { + return xml(this.XMLData); + } + get XMLData() { + return [ + { expirationDate: this.expirationDate }, + { billing: this.billing.XML }, + { registrar: this.registrar }, + { admin: this.admin.XML }, + { domainName: this.domainName }, + { creationDate: this.creationDate }, + { tech: this.tech.XML }, + { updatedDate: this.updatedDate }, + { registrant: this.registrant.XML }, + { status: this.status }, + ]; + } + get YAML() { + return yaml.stringify(this.JSON); + } +} + +class Full { + constructor(data) { + this.WHOIS = new WHOIS(data.whois); + this.DNS = new DNS(data.dns); + } + get JSON() { + return { + whois: this.WHOIS.JSON, + dns: this.DNS.JSON, + }; + } + get XML() { + return xml({ + full: [ + { whois: this.WHOIS.XMLData }, + { dns: this.DNS.XMLData }, + ], + }); + } + get YAML() { } +} + +class Crypto { + static DNS = DNS; + static WHOIS = WHOIS; + static Full = Full; +} + +module.exports = Crypto; diff --git a/package-lock.json b/package-lock.json index fcaba6a..5518f71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,7 +61,8 @@ "vhost": "^3.0.2", "whoiser": "^1.17.3", "ws": "^8.17.1", - "xml": "^1.0.1" + "xml": "^1.0.1", + "yaml": "^2.4.5" }, "devDependencies": { "@eslint/js": "^9.3.0", @@ -7851,9 +7852,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", - "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "license": "ISC", "bin": { "yaml": "bin.mjs" diff --git a/package.json b/package.json index 3d388bd..b516fa2 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,8 @@ "vhost": "^3.0.2", "whoiser": "^1.17.3", "ws": "^8.17.1", - "xml": "^1.0.1" + "xml": "^1.0.1", + "yaml": "^2.4.5" }, "devDependencies": { "@eslint/js": "^9.3.0", diff --git a/web/api/routes/location.js b/web/api/routes/location.js index f0ae858..94298b8 100644 --- a/web/api/routes/location.js +++ b/web/api/routes/location.js @@ -1,5 +1,6 @@ const router = require('express').Router(), + LocationFormatter = require('../../../modules/api/location'), fullDataToLocationData = ({ results: [info] }) => Object.assign( { @@ -46,7 +47,20 @@ router }); const data = JSON.parse(results.data); if (data.status === 'ZERO_RESULTS') return res.sendError(13); - res.json({ data: fullDataToLocationData(data) }); + const fData = new LocationFormatter(fullDataToLocationData(data)); + switch (req.query.type) { + case 'xml': + return res + .setHeader('Content-Type', 'application/xml') + .send(fData.XML); + case 'yaml': + return res + .setHeader('Content-Type', 'application/yaml') + .send(fData.YAML); + case 'json': + default: + return res.json(fData.JSON); + } }) .get('/pluscode', async (req, res) => { if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Location::Pluscode', allowMgr: true }))) return; @@ -61,7 +75,20 @@ router }); const data = JSON.parse(results.data); if (data.status === 'ZERO_RESULTS') return res.sendError(13); - res.json({ data: fullDataToLocationData(data) }); + const fData = new LocationFormatter(fullDataToLocationData(data)); + switch (req.query.type) { + case 'xml': + return res + .setHeader('Content-Type', 'application/xml') + .send(fData.XML); + case 'yaml': + return res + .setHeader('Content-Type', 'application/yaml') + .send(fData.YAML); + case 'json': + default: + return res.json(fData.JSON); + } }) .get('/address', async (req, res) => { if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Location::Address', allowMgr: true }))) return; @@ -76,7 +103,20 @@ router }); const data = JSON.parse(results.data); if (data.status === 'ZERO_RESULTS') return res.sendError(13); - res.json({ data: fullDataToLocationData(data) }); + const fData = new LocationFormatter(fullDataToLocationData(data)); + switch (req.query.type) { + case 'xml': + return res + .setHeader('Content-Type', 'application/xml') + .send(fData.XML); + case 'yaml': + return res + .setHeader('Content-Type', 'application/yaml') + .send(fData.YAML); + case 'json': + default: + return res.json(fData.JSON); + } }) .use((req, res, next) => { const { path } = req; diff --git a/web/api/routes/phone.js b/web/api/routes/phone.js index 0d44dc9..1cb84db 100644 --- a/web/api/routes/phone.js +++ b/web/api/routes/phone.js @@ -1,4 +1,5 @@ const router = require('express').Router(); +const PhoneFormatter = require('../../../modules/api/phone'); require('dotenv').config(); router @@ -16,7 +17,20 @@ router }, }); if (AxiosRes.status === 404) return res.sendError(22); - res.json(JSON.parse(AxiosRes.data)); + const fData = new PhoneFormatter(AxiosRes.data); + switch (req.query.type) { + case 'xml': + return res + .setHeader('Content-Type', 'application/xml') + .send(fData.XML); + case 'yaml': + return res + .setHeader('Content-Type', 'application/yaml') + .send(fData.YAML); + case 'json': + default: + return res.json(fData.JSON); + } }) .use((req, res, next) => { const { path } = req; diff --git a/web/api/routes/quotes.js b/web/api/routes/quotes.js index f25ed38..8afceac 100644 --- a/web/api/routes/quotes.js +++ b/web/api/routes/quotes.js @@ -1,25 +1,74 @@ const router = require('express').Router(); +const QuoteFormatter = require('../../../modules/api/quote'); router .get('/kanye', async (req, res) => { if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Quote::Kanye', allowMgr: true }))) return; const { data } = await req.axiosReq('https://api.kanye.rest'); - res.send(JSON.parse(data).quote); + const fData = new QuoteFormatter({ + quote: JSON.parse(data).quote, + author: 'Kanye West', + tags: [], + }); + switch (req.query.type) { + case 'xml': + return res + .setHeader('Content-Type', 'application/xml') + .send(fData.XML); + case 'yaml': + return res + .setHeader('Content-Type', 'application/yaml') + .send(fData.YAML); + case 'json': + default: + return res.json(fData.JSON); + } }) .get('/ronswanson', async (req, res) => { if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Quote::RonSwanson', allowMgr: true }))) return; const { data } = await req.axiosReq('https://ron-swanson-quotes.herokuapp.com/v2/quotes'); - res.send(JSON.parse(data)[0]); + // res.send(JSON.parse(data)[0]); + const fData = new QuoteFormatter({ + quote: JSON.parse(data)[0], + author: 'Ron Swanson', + tags: [], + }); + switch (req.query.type) { + case 'xml': + return res + .setHeader('Content-Type', 'application/xml') + .send(fData.XML); + case 'yaml': + return res + .setHeader('Content-Type', 'application/yaml') + .send(fData.YAML); + case 'json': + default: + return res.json(fData.JSON); + } }) .get('/random', async (req, res) => { if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Quote::Random', allowMgr: true }))) return; const { data } = await req.axiosReq('https://api.quotable.io/random'); const ResData = JSON.parse(data); - res.json({ - content: ResData.content, + const fData = new QuoteFormatter({ + quote: ResData.content, author: ResData.author, tags: ResData.tags, }); + switch (req.query.type) { + case 'xml': + return res + .setHeader('Content-Type', 'application/xml') + .send(fData.XML); + case 'yaml': + return res + .setHeader('Content-Type', 'application/yaml') + .send(fData.YAML); + case 'json': + default: + return res.json(fData.JSON); + } }) .use((req, res, next) => { const { path } = req; diff --git a/web/api/routes/router.js b/web/api/routes/router.js index 20432be..560c553 100644 --- a/web/api/routes/router.js +++ b/web/api/routes/router.js @@ -10,15 +10,12 @@ const errorResponse = k => require('../../../functions/errorResponse').get(k); const User = require('../../../functions/userMgr'); //- Routes -const user = require('./user'); const mail = require('./mail'); -const token = require('./token'); const facts = require('./facts'); const phone = require('./phone'); const whois = require('./whois'); const crypto = require('./crypto'); const quotes = require('./quotes'); -const weather = require('./weather'); const barcode = require('./barcode'); const location = require('./location'); const password = require('./password'); @@ -76,15 +73,12 @@ router .get('/robots.txt', (_, res) => res.setHeader('Content-Type', 'text/plain; charset=utf8').sendFile(`${__dirname}/meta/robots.txt`)) .get('/sitemap', (_, res) => res.setHeader('Content-Type', 'text/xml; charset=utf8').sendFile(`${__dirname}/meta/sitemap.xml`)) .use(APIAuth, express.json()) - .use('/user', user) .use('/mail', mail) - .use('/token', token) .use('/facts', facts) .use('/phone', phone) .use('/whois', whois) .use('/crypto', crypto) .use('/quotes', quotes) - .use('/weather', weather) .use('/barcode', barcode) .use('/location', location) .use('/password', password) diff --git a/web/api/routes/token.js b/web/api/routes/token.js deleted file mode 100644 index 552167c..0000000 --- a/web/api/routes/token.js +++ /dev/null @@ -1,93 +0,0 @@ -const router = require('express').Router(); -const crypto = require('crypto'); -const wUtils = require('@therealbenpai/webutils'); - -router - .post('/create', async (req, res) => { - if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Global::Token.Create', allowMgr: true }))) return; - const connection = await req.Database.pool.connect(); - const { firebaseuid } = req.body; - if (!firebaseuid) return res.status(400).json({ error: 'No firebaseuid provided' }); - const { rows: userRows } = await connection.query(`SELECT * FROM public.users WHERE firebaseuid = '${firebaseuid}'`); - const generatedToken = wUtils.Crypt.Manual - .encrypt( - `${firebaseuid}.${userRows[0].displayname}:${crypto.randomBytes(16).toString('base64url')}`, - process.env.C_IV, - process.env.C_KEY, - ); - req.Database.emit('token', { generatedToken, firebaseuid }); - res.status(201).json({ token: generatedToken }); - connection.release(); - // const {associatedfirebaseuid: FirebaseUser} = rows[0]; - // AdminApp.auth().getUser(FirebaseUser) - }) - .delete('/delete', async (req, res) => { - if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Global::Token.Delete', allowMgr: true }))) return; - const connection = await req.Database.pool.connect(); - const { token: tokenToDelete } = req.body; - if (!tokenToDelete) return res.sendError(10); - const { rows: tokenRows } = await connection.query(`SELECT * FROM public.APITokens WHERE token = '${tokenToDelete}'`); - if (tokenRows.length === 0) return res.sendError(21); - if (res.headersSent) return; - await connection.query(`DELETE FROM public.APITokens WHERE token = '${tokenToDelete}'`).catch(_ => res.sendError(21)); - if (res.headersSent) return; - await connection.query(`DELETE FROM public.apiUsage WHERE apiToken = '${tokenToDelete}'`).catch(_ => res.sendError(21)); - if (res.headersSent) return; - res.status(200).json({ message: 'Token deleted' }); - connection.release(); - }) - .get('/list', async (req, res) => { - if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Global::Token.ReadAll', allowMgr: true }))) return; - const connection = await req.Database.pool.connect(); - const { rows: tokens } = (await connection.query("SELECT * FROM public.APITokens")); - const formattedTokens = []; - for (const tokenData of tokens) { - const { rows: [user] } = ( - await connection.query(`SELECT * FROM public.users WHERE firebaseuid = '${tokenData.associatedfirebaseuid}' LIMIT 1`) - ); - formattedTokens.push({ - token: tokenData.token, - username: user.displayname, - firebaseuid: user.firebaseuid, - }); - } - res.status(200).json(formattedTokens); - connection.release(); - }) - .get('/info', async (req, res) => { - if (req.query.token && !(await req.checkPermissions(req, res, { multi: false, perm: 'Global::Token.Read', allowMgr: true }))) return; - const connection = await req.Database.pool.connect(); - const [_, token] = req.headers['authorization'].split(' '); - const { rows } = await connection.query(`SELECT * FROM public.APITokens WHERE token = '${req.query.token || token}'`); - if (rows.length === 0) return res.sendError(18); - const { rows: userRows } = await connection.query(`SELECT * FROM public.users WHERE firebaseuid = '${rows[0].associatedfirebaseuid}'`); - if (userRows.length === 0) return res.sendError(18); - await connection.release(); - res.status(200).json({ - token: rows[0].token, - username: userRows[0].displayName, - firebaseuid: userRows[0].firebaseuid, - }); - }) - .use((req, res, next) => { - const { path } = req; - const methodUsed = req.method.toUpperCase(); - let allowedMethods = router.stack.filter(routerObj => routerObj.route && routerObj.route.path === path); - if (allowedMethods.length === 0) return next(); - allowedMethods.map(routerObj => routerObj.route.stack[0]); - allowedMethods = { ...allowedMethods[0] }; - allowedMethods = allowedMethods.route.methods; - if (req.method === 'OPTIONS') - return res.setHeader('Allow', Object.keys(allowedMethods) - .map(verb => verb.toUpperCase()).join(', ')) - .setHeader('Access-Control-Allow-Methods', Object.keys(allowedMethods).map(verb => verb.toUpperCase()).join(', ')) - .status(204) - .send(); - if (allowedMethods[methodUsed]) return next(); - return res.status(405).render( - "misc/405.pug", - req.getErrPage(405, { path, allowedMethods, methodUsed }), - ); - }); - -module.exports = router; diff --git a/web/api/routes/user.js b/web/api/routes/user.js deleted file mode 100644 index 8e3a822..0000000 --- a/web/api/routes/user.js +++ /dev/null @@ -1,123 +0,0 @@ -const router = require('express').Router(); - -router - .get('/get', async (req, res) => { - if (req.headers['x-uid'] && !(await req.checkPermissions(req, res, { multi: false, perm: 'Global::User.Read', allowMgr: true }))) return; - const connection = await req.Database.pool.connect(); - const { rows } = await connection.query(`SELECT * FROM public.APITokens WHERE token = '${req.headers['authorization'].split(' ')[1]}'`); - if (rows.length === 0) return res.sendError(4); - const { associatedfirebaseuid: firebaseUserID } = rows[0]; - const { rows: DBUserData } = await connection.query( - `SELECT * FROM public.users WHERE firebaseuid = '${req.headers['x-uid'] || firebaseUserID}'`, - ); - if (DBUserData.length === 0) return res.sendError(14); - const firebaseUser = await req.FirebaseAdmin.auth().getUser(req.headers['x-uid'] || firebaseUserID); - if (!firebaseUser) return res.sendError(14); - const userData = Object.assign({}, firebaseUser, DBUserData[0]); - return res.status(200).json({ - id: userData.uid, - username: userData.displayName, - fullName: `${userData.firstname} ${userData.lastname}`, - email: userData.email, - permissions: userData.permissions, - }); - }) - .post('/create', async (req, res) => { - if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Global::User.Create', allowMgr: true }))) return; - const { username, firstname, lastname, email, password } = req.body; - if (!username || !firstname || !lastname || !email || !password) return res.sendError(10); - const newUser = await req.auth - .createUser({ - displayName: username, - email, - password, - }) - .catch(err => res.sendError(15)); - if (res.headersSent) return; - req.Database.emit('user', { uid: newUser.uid, displayName: username, firstname, lastname, email, permissions: '' }); - return res.status(201).json({ - user: newUser, - username, - fullName: `${firstname} ${lastname}`, - email, - permissions: '', - }); - }) - .patch('/update', async (req, res) => { - if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Global::User.Write', allowMgr: true }))) return; - const connection = await req.Database.pool.connect(); - const uid = req.headers['x-uid']; - for (const [key, value] of Object.entries(req.body)) { - switch (key) { - default: if (res.headersSent) return; //! If the response has already been sent, returns to prevent an error - case "displayname": - req.auth.updateUser(uid, { displayName: value || null }) - .catch(_ => req.sendError(16)); - connection - .query(`UPDATE public.users SET displayname = '${value}' WHERE firebaseuid = '${uid}'`); - break; - case "email": - req.auth.updateUser(uid, { email: value }) - .catch(_ => req.sendError(16)); - connection - .query(`UPDATE public.users SET email = '${value}' WHERE firebaseuid = '${uid}'`); - break; - case "password": - req.auth.updateUser(uid, { password: value }) - .catch(_ => req.sendError(16)); - break; - case "perms": - connection - .query(`UPDATE public.users SET permissions = '${value}' WHERE firebaseuid = '${uid}'`) - .catch(_ => req.sendError(16)); - break; - } - } - const { rows: updatedDBUser } = await connection.query(`SELECT * FROM public.users WHERE firebaseuid = '${uid}'`); - await connection.release(); - return res.status(200).json({ - id: uid, - updatedUser: { - ...req.auth.getUser(uid), - ...updatedDBUser[0], - }, - }); - }) - .delete('/delete', async (req, res) => { - if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Global::User.Delete', allowMgr: true }))) return; - const connection = await req.Database.pool.connect(); - const uid = req.headers['x-uid']; - await req.auth.deleteUser(uid) - .catch(_ => req.sendError(17)); - if (res.headersSent) return; - await connection.query(`DELETE FROM public.users WHERE firebaseuid = '${uid}'`) - .catch(_ => req.sendError(17)); - if (res.headersSent) return; - await connection.release(); - return res.status(200).json({ - id: uid, - deleted: true, - }); - }) - .use((req, res, next) => { - const { path } = req; - const methodUsed = req.method.toUpperCase(); - let allowedMethods = router.stack.filter(routerObj => routerObj.route && routerObj.route.path === path); - if (allowedMethods.length === 0) return next(); - allowedMethods.map(routerObj => routerObj.route.stack[0]); - allowedMethods = { ...allowedMethods[0] }; - allowedMethods = allowedMethods.route.methods; - if (req.method === 'OPTIONS') - return res.setHeader('Allow', Object.keys(allowedMethods) - .map(verb => verb.toUpperCase()).join(', ')) - .setHeader('Access-Control-Allow-Methods', Object.keys(allowedMethods).map(verb => verb.toUpperCase()).join(', ')) - .status(204) - .send(); - if (allowedMethods[methodUsed]) return next(); - return res.status(405).render( - "misc/405.pug", - req.getErrPage(405, { path, allowedMethods, methodUsed }), - ); - }); - -module.exports = router; diff --git a/web/api/routes/weather.js b/web/api/routes/weather.js deleted file mode 100644 index 4c652ff..0000000 --- a/web/api/routes/weather.js +++ /dev/null @@ -1,55 +0,0 @@ -const router = require('express').Router(); - -router - .get('/current', async (req, res) => { - if (!(await req.checkPermissions(req, res, { multi: false, perm: 'Weather::Current', allowMgr: true }))) return; - let lat, lon; - if (req.headers['x-city']) { - const AxiosRes = await req.axiosReq("/json", { - baseURL: 'https://maps.googleapis.com/maps/api/geocode', - params: { - address: req.headers['x-city'], - key: process.env.GMAPS_API_KEY, - }, - }); - const data = JSON.parse(AxiosRes.data); - if (data.status === 'ZERO_RESULTS') return res.sendError(13); - lat = data.results[0].geometry.location.lat; - lon = data.results[0].geometry.location.lng; - } else if (req.query.lat && req.query.lon) [lat, lon] = req.headers['x-coords'].split(','); - else return res.sendError(6); - const AxiosRes = await req.axiosReq("/weather", { - baseURL: 'https://api.openweathermap.org/data/2.5', - params: { - appid: process.env.OPEN_WEATHER_API_KEY, - mode: 'json', - units: 'imperial', - lat, - lon, - }, - }); - if (AxiosRes.status === 400) return res.sendError(22); - res.json(JSON.parse(AxiosRes.data)); - }) - .use((req, res, next) => { - const { path } = req; - const methodUsed = req.method.toUpperCase(); - let allowedMethods = router.stack.filter(routerObj => routerObj.route && routerObj.route.path === path); - if (allowedMethods.length === 0) return next(); - allowedMethods.map(routerObj => routerObj.route.stack[0]); - allowedMethods = { ...allowedMethods[0] }; - allowedMethods = allowedMethods.route.methods; - if (req.method === 'OPTIONS') - return res.setHeader('Allow', Object.keys(allowedMethods) - .map(verb => verb.toUpperCase()).join(', ')) - .setHeader('Access-Control-Allow-Methods', Object.keys(allowedMethods).map(verb => verb.toUpperCase()).join(', ')) - .status(204) - .send(); - if (allowedMethods[methodUsed]) return next(); - return res.status(405).render( - "misc/405.pug", - req.getErrPage(405, { path, allowedMethods, methodUsed }), - ); - }); - -module.exports = router;