[MAJOR][FIRSTCOMMIT] Added basic routes, controllers, repos to kanban service (no postgres yet)

This commit is contained in:
2025-09-27 14:09:35 +05:30
parent f283f6043f
commit fd7ceca2ef
109 changed files with 3554 additions and 444 deletions

29
lib/constants/EnvVars.js Normal file
View File

@@ -0,0 +1,29 @@
"use strict";
/**
* Environments variables declared here.
*/
var _a, _b, _c, _d, _e, _f, _g;
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable node/no-process-env */
exports.default = {
NodeEnv: ((_a = process.env.NODE_ENV) !== null && _a !== void 0 ? _a : ''),
Port: ((_b = process.env.PORT) !== null && _b !== void 0 ? _b : 0),
CookieProps: {
Key: 'ExpressGeneratorTs',
Secret: ((_c = process.env.COOKIE_SECRET) !== null && _c !== void 0 ? _c : ''),
// Casing to match express cookie options
Options: {
httpOnly: true,
signed: true,
path: ((_d = process.env.COOKIE_PATH) !== null && _d !== void 0 ? _d : ''),
maxAge: Number((_e = process.env.COOKIE_EXP) !== null && _e !== void 0 ? _e : 0),
domain: ((_f = process.env.COOKIE_DOMAIN) !== null && _f !== void 0 ? _f : ''),
secure: (process.env.SECURE_COOKIE === 'true'),
},
},
Jwt: {
Secret: ((_g = process.env.JWT_SECRET) !== null && _g !== void 0 ? _g : ''),
Exp: (process.env.COOKIE_EXP && process.env.COOKIE_EXP !== '' ? process.env.COOKIE_EXP : '1h'), // exp at the same time as the cookie
},
};
//# sourceMappingURL=EnvVars.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"EnvVars.js","sourceRoot":"","sources":["../../src/constants/EnvVars.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,wCAAwC;AAGxC,kBAAe;IACb,OAAO,EAAE,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,QAAQ,mCAAI,EAAE,CAAC;IACrC,IAAI,EAAE,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,IAAI,mCAAI,CAAC,CAAC;IAC7B,WAAW,EAAE;QACX,GAAG,EAAE,oBAAoB;QACzB,MAAM,EAAE,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,aAAa,mCAAI,EAAE,CAAC;QACzC,yCAAyC;QACzC,OAAO,EAAE;YACP,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,WAAW,mCAAI,EAAE,CAAC;YACrC,MAAM,EAAE,MAAM,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,UAAU,mCAAI,CAAC,CAAC;YAC3C,MAAM,EAAE,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,aAAa,mCAAI,EAAE,CAAC;YACzC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,MAAM,CAAC;SAC/C;KACF;IACD,GAAG,EAAE;QACH,MAAM,EAAE,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,UAAU,mCAAK,EAAE,CAAC;QACvC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,qCAAqC;KACtI;CACO,CAAC"}

View File

@@ -0,0 +1,327 @@
"use strict";
/* eslint-disable max-len */
/**
* This file was copied from here: https://gist.github.com/scokmen/f813c904ef79022e84ab2409574d1b45
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Hypertext Transfer Protocol (HTTP) response status codes.
* @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
*/
var HttpStatusCodes;
(function (HttpStatusCodes) {
/**
* The server has received the request headers and the client should proceed to send the request body
* (in the case of a request for which a body needs to be sent; for example, a POST request).
* Sending a large request body to a server after a request has been rejected for inappropriate headers would be inefficient.
* To have a server check the request's headers, a client must send Expect: 100-continue as a header in its initial request
* and receive a 100 Continue status code in response before sending the body. The response 417 Expectation Failed indicates the request should not be continued.
*/
HttpStatusCodes[HttpStatusCodes["CONTINUE"] = 100] = "CONTINUE";
/**
* The requester has asked the server to switch protocols and the server has agreed to do so.
*/
HttpStatusCodes[HttpStatusCodes["SWITCHING_PROTOCOLS"] = 101] = "SWITCHING_PROTOCOLS";
/**
* A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request.
* This code indicates that the server has received and is processing the request, but no response is available yet.
* This prevents the client from timing out and assuming the request was lost.
*/
HttpStatusCodes[HttpStatusCodes["PROCESSING"] = 102] = "PROCESSING";
/**
* Standard response for successful HTTP requests.
* The actual response will depend on the request method used.
* In a GET request, the response will contain an entity corresponding to the requested resource.
* In a POST request, the response will contain an entity describing or containing the result of the action.
*/
HttpStatusCodes[HttpStatusCodes["OK"] = 200] = "OK";
/**
* The request has been fulfilled, resulting in the creation of a new resource.
*/
HttpStatusCodes[HttpStatusCodes["CREATED"] = 201] = "CREATED";
/**
* The request has been accepted for processing, but the processing has not been completed.
* The request might or might not be eventually acted upon, and may be disallowed when processing occurs.
*/
HttpStatusCodes[HttpStatusCodes["ACCEPTED"] = 202] = "ACCEPTED";
/**
* SINCE HTTP/1.1
* The server is a transforming proxy that received a 200 OK from its origin,
* but is returning a modified version of the origin's response.
*/
HttpStatusCodes[HttpStatusCodes["NON_AUTHORITATIVE_INFORMATION"] = 203] = "NON_AUTHORITATIVE_INFORMATION";
/**
* The server successfully processed the request and is not returning any content.
*/
HttpStatusCodes[HttpStatusCodes["NO_CONTENT"] = 204] = "NO_CONTENT";
/**
* The server successfully processed the request, but is not returning any content.
* Unlike a 204 response, this response requires that the requester reset the document view.
*/
HttpStatusCodes[HttpStatusCodes["RESET_CONTENT"] = 205] = "RESET_CONTENT";
/**
* The server is delivering only part of the resource (byte serving) due to a range header sent by the client.
* The range header is used by HTTP clients to enable resuming of interrupted downloads,
* or split a download into multiple simultaneous streams.
*/
HttpStatusCodes[HttpStatusCodes["PARTIAL_CONTENT"] = 206] = "PARTIAL_CONTENT";
/**
* The message body that follows is an XML message and can contain a number of separate response codes,
* depending on how many sub-requests were made.
*/
HttpStatusCodes[HttpStatusCodes["MULTI_STATUS"] = 207] = "MULTI_STATUS";
/**
* The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response,
* and are not being included again.
*/
HttpStatusCodes[HttpStatusCodes["ALREADY_REPORTED"] = 208] = "ALREADY_REPORTED";
/**
* The server has fulfilled a request for the resource,
* and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
*/
HttpStatusCodes[HttpStatusCodes["IM_USED"] = 226] = "IM_USED";
/**
* Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation).
* For example, this code could be used to present multiple video format options,
* to list files with different filename extensions, or to suggest word-sense disambiguation.
*/
HttpStatusCodes[HttpStatusCodes["MULTIPLE_CHOICES"] = 300] = "MULTIPLE_CHOICES";
/**
* This and all future requests should be directed to the given URI.
*/
HttpStatusCodes[HttpStatusCodes["MOVED_PERMANENTLY"] = 301] = "MOVED_PERMANENTLY";
/**
* This is an example of industry practice contradicting the standard.
* The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect
* (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302
* with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307
* to distinguish between the two behaviours. However, some Web applications and frameworks
* use the 302 status code as if it were the 303.
*/
HttpStatusCodes[HttpStatusCodes["FOUND"] = 302] = "FOUND";
/**
* SINCE HTTP/1.1
* The response to the request can be found under another URI using a GET method.
* When received in response to a POST (or PUT/DELETE), the client should presume that
* the server has received the data and should issue a redirect with a separate GET message.
*/
HttpStatusCodes[HttpStatusCodes["SEE_OTHER"] = 303] = "SEE_OTHER";
/**
* Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.
* In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.
*/
HttpStatusCodes[HttpStatusCodes["NOT_MODIFIED"] = 304] = "NOT_MODIFIED";
/**
* SINCE HTTP/1.1
* The requested resource is available only through a proxy, the address for which is provided in the response.
* Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, primarily for security reasons.
*/
HttpStatusCodes[HttpStatusCodes["USE_PROXY"] = 305] = "USE_PROXY";
/**
* No longer used. Originally meant "Subsequent requests should use the specified proxy."
*/
HttpStatusCodes[HttpStatusCodes["SWITCH_PROXY"] = 306] = "SWITCH_PROXY";
/**
* SINCE HTTP/1.1
* In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
* In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the original request.
* For example, a POST request should be repeated using another POST request.
*/
HttpStatusCodes[HttpStatusCodes["TEMPORARY_REDIRECT"] = 307] = "TEMPORARY_REDIRECT";
/**
* The request and all future requests should be repeated using another URI.
* 307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change.
* So, for example, submitting a form to a permanently redirected resource may continue smoothly.
*/
HttpStatusCodes[HttpStatusCodes["PERMANENT_REDIRECT"] = 308] = "PERMANENT_REDIRECT";
/**
* The server cannot or will not process the request due to an apparent client error
* (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing).
*/
HttpStatusCodes[HttpStatusCodes["BAD_REQUEST"] = 400] = "BAD_REQUEST";
/**
* Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet
* been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the
* requested resource. See Basic access authentication and Digest access authentication. 401 semantically means
* "unauthenticated",i.e. the user does not have the necessary credentials.
*/
HttpStatusCodes[HttpStatusCodes["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
/**
* Reserved for future use. The original intention was that this code might be used as part of some form of digital
* cash or micro payment scheme, but that has not happened, and this code is not usually used.
* Google Developers API uses this status if a particular developer has exceeded the daily limit on requests.
*/
HttpStatusCodes[HttpStatusCodes["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
/**
* The request was valid, but the server is refusing action.
* The user might not have the necessary permissions for a resource.
*/
HttpStatusCodes[HttpStatusCodes["FORBIDDEN"] = 403] = "FORBIDDEN";
/**
* The requested resource could not be found but may be available in the future.
* Subsequent requests by the client are permissible.
*/
HttpStatusCodes[HttpStatusCodes["NOT_FOUND"] = 404] = "NOT_FOUND";
/**
* A request method is not supported for the requested resource;
* for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
*/
HttpStatusCodes[HttpStatusCodes["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
/**
* The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
*/
HttpStatusCodes[HttpStatusCodes["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
/**
* The client must first authenticate itself with the proxy.
*/
HttpStatusCodes[HttpStatusCodes["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
/**
* The server timed out waiting for the request.
* According to HTTP specifications:
* "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
*/
HttpStatusCodes[HttpStatusCodes["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
/**
* Indicates that the request could not be processed because of conflict in the request,
* such as an edit conflict between multiple simultaneous updates.
*/
HttpStatusCodes[HttpStatusCodes["CONFLICT"] = 409] = "CONFLICT";
/**
* Indicates that the resource requested is no longer available and will not be available again.
* This should be used when a resource has been intentionally removed and the resource should be purged.
* Upon receiving a 410 status code, the client should not request the resource in the future.
* Clients such as search engines should remove the resource from their indices.
* Most use cases do not require clients and search engines to purge the resource, and a "404 Not Found" may be used instead.
*/
HttpStatusCodes[HttpStatusCodes["GONE"] = 410] = "GONE";
/**
* The request did not specify the length of its content, which is required by the requested resource.
*/
HttpStatusCodes[HttpStatusCodes["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
/**
* The server does not meet one of the preconditions that the requester put on the request.
*/
HttpStatusCodes[HttpStatusCodes["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
/**
* The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".
*/
HttpStatusCodes[HttpStatusCodes["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
/**
* The URI provided was too long for the server to process. Often the result of too much data being encoded as a query-string of a GET request,
* in which case it should be converted to a POST request.
* Called "Request-URI Too Long" previously.
*/
HttpStatusCodes[HttpStatusCodes["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
/**
* The request entity has a media type which the server or resource does not support.
* For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
*/
HttpStatusCodes[HttpStatusCodes["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
/**
* The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.
* For example, if the client asked for a part of the file that lies beyond the end of the file.
* Called "Requested Range Not Satisfiable" previously.
*/
HttpStatusCodes[HttpStatusCodes["RANGE_NOT_SATISFIABLE"] = 416] = "RANGE_NOT_SATISFIABLE";
/**
* The server cannot meet the requirements of the Expect request-header field.
*/
HttpStatusCodes[HttpStatusCodes["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
/**
* This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
* and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
* teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com.
*/
HttpStatusCodes[HttpStatusCodes["I_AM_A_TEAPOT"] = 418] = "I_AM_A_TEAPOT";
/**
* The request was directed at a server that is not able to produce a response (for example because a connection reuse).
*/
HttpStatusCodes[HttpStatusCodes["MISDIRECTED_REQUEST"] = 421] = "MISDIRECTED_REQUEST";
/**
* The request was well-formed but was unable to be followed due to semantic errors.
*/
HttpStatusCodes[HttpStatusCodes["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
/**
* The resource that is being accessed is locked.
*/
HttpStatusCodes[HttpStatusCodes["LOCKED"] = 423] = "LOCKED";
/**
* The request failed due to failure of a previous request (e.g., a PROPPATCH).
*/
HttpStatusCodes[HttpStatusCodes["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
/**
* The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.
*/
HttpStatusCodes[HttpStatusCodes["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED";
/**
* The origin server requires the request to be conditional.
* Intended to prevent "the 'lost update' problem, where a client
* GETs a resource's state, modifies it, and PUTs it back to the server,
* when meanwhile a third party has modified the state on the server, leading to a conflict."
*/
HttpStatusCodes[HttpStatusCodes["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
/**
* The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes.
*/
HttpStatusCodes[HttpStatusCodes["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
/**
* The server is unwilling to process the request because either an individual header field,
* or all the header fields collectively, are too large.
*/
HttpStatusCodes[HttpStatusCodes["REQUEST_HEADER_FIELDS_TOO_LARGE"] = 431] = "REQUEST_HEADER_FIELDS_TOO_LARGE";
/**
* A server operator has received a legal demand to deny access to a resource or to a set of resources
* that includes the requested resource. The code 451 was chosen as a reference to the novel Fahrenheit 451.
*/
HttpStatusCodes[HttpStatusCodes["UNAVAILABLE_FOR_LEGAL_REASONS"] = 451] = "UNAVAILABLE_FOR_LEGAL_REASONS";
/**
* A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
*/
HttpStatusCodes[HttpStatusCodes["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
/**
* The server either does not recognize the request method, or it lacks the ability to fulfill the request.
* Usually this implies future availability (e.g., a new feature of a web-service API).
*/
HttpStatusCodes[HttpStatusCodes["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
/**
* The server was acting as a gateway or proxy and received an invalid response from the upstream server.
*/
HttpStatusCodes[HttpStatusCodes["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
/**
* The server is currently unavailable (because it is overloaded or down for maintenance).
* Generally, this is a temporary state.
*/
HttpStatusCodes[HttpStatusCodes["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
/**
* The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
*/
HttpStatusCodes[HttpStatusCodes["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
/**
* The server does not support the HTTP protocol version used in the request
*/
HttpStatusCodes[HttpStatusCodes["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
/**
* Transparent content negotiation for the request results in a circular reference.
*/
HttpStatusCodes[HttpStatusCodes["VARIANT_ALSO_NEGOTIATES"] = 506] = "VARIANT_ALSO_NEGOTIATES";
/**
* The server is unable to store the representation needed to complete the request.
*/
HttpStatusCodes[HttpStatusCodes["INSUFFICIENT_STORAGE"] = 507] = "INSUFFICIENT_STORAGE";
/**
* The server detected an infinite loop while processing the request.
*/
HttpStatusCodes[HttpStatusCodes["LOOP_DETECTED"] = 508] = "LOOP_DETECTED";
/**
* Further extensions to the request are required for the server to fulfill it.
*/
HttpStatusCodes[HttpStatusCodes["NOT_EXTENDED"] = 510] = "NOT_EXTENDED";
/**
* The client needs to authenticate to gain network access.
* Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used
* to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
*/
HttpStatusCodes[HttpStatusCodes["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
})(HttpStatusCodes || (HttpStatusCodes = {}));
exports.default = HttpStatusCodes;
//# sourceMappingURL=HttpStatusCodes.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"HttpStatusCodes.js","sourceRoot":"","sources":["../../src/constants/HttpStatusCodes.ts"],"names":[],"mappings":";AAAA,4BAA4B;AAC5B;;GAEG;;AAEH;;;GAGG;AACH,IAAK,eAsXJ;AAtXD,WAAK,eAAe;IAEhB;;;;;;OAMG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;;;OAIG;IACH,mEAAgB,CAAA;IAEhB;;;;;OAKG;IACH,mDAAQ,CAAA;IAER;;OAEG;IACH,6DAAa,CAAA;IAEb;;;OAGG;IACH,+DAAc,CAAA;IAEd;;;;OAIG;IACH,yGAAmC,CAAA;IAEnC;;OAEG;IACH,mEAAgB,CAAA;IAEhB;;;OAGG;IACH,yEAAmB,CAAA;IAEnB;;;;OAIG;IACH,6EAAqB,CAAA;IAErB;;;OAGG;IACH,uEAAkB,CAAA;IAElB;;;OAGG;IACH,+EAAsB,CAAA;IAEtB;;;OAGG;IACH,6DAAa,CAAA;IAEb;;;;OAIG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;;;;;;OAOG;IACH,yDAAW,CAAA;IAEX;;;;;OAKG;IACH,iEAAe,CAAA;IAEf;;;OAGG;IACH,uEAAkB,CAAA;IAElB;;;;OAIG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,uEAAkB,CAAA;IAElB;;;;;OAKG;IACH,mFAAwB,CAAA;IAExB;;;;OAIG;IACH,mFAAwB,CAAA;IAExB;;;OAGG;IACH,qEAAiB,CAAA;IAEjB;;;;;OAKG;IACH,uEAAkB,CAAA;IAElB;;;;OAIG;IACH,+EAAsB,CAAA;IAEtB;;;OAGG;IACH,iEAAe,CAAA;IAEf;;;OAGG;IACH,iEAAe,CAAA;IAEf;;;OAGG;IACH,mFAAwB,CAAA;IAExB;;OAEG;IACH,2EAAoB,CAAA;IAEpB;;OAEG;IACH,yGAAmC,CAAA;IAEnC;;;;OAIG;IACH,6EAAqB,CAAA;IAErB;;;OAGG;IACH,+DAAc,CAAA;IAEd;;;;;;OAMG;IACH,uDAAU,CAAA;IAEV;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;;;OAIG;IACH,uEAAkB,CAAA;IAElB;;;OAGG;IACH,2FAA4B,CAAA;IAE5B;;;;OAIG;IACH,yFAA2B,CAAA;IAE3B;;OAEG;IACH,mFAAwB,CAAA;IAExB;;;;OAIG;IACH,yEAAmB,CAAA;IAEnB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,2DAAY,CAAA;IAEZ;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;;;;OAKG;IACH,yFAA2B,CAAA;IAE3B;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;;OAGG;IACH,6GAAqC,CAAA;IAErC;;;OAGG;IACH,yGAAmC,CAAA;IAEnC;;OAEG;IACH,yFAA2B,CAAA;IAE3B;;;OAGG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,qEAAiB,CAAA;IAEjB;;;OAGG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,mGAAgC,CAAA;IAEhC;;OAEG;IACH,6FAA6B,CAAA;IAE7B;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,yEAAmB,CAAA;IAEnB;;OAEG;IACH,uEAAkB,CAAA;IAElB;;;;OAIG;IACH,6GAAqC,CAAA;AACzC,CAAC,EAtXI,eAAe,KAAf,eAAe,QAsXnB;AAED,kBAAe,eAAe,CAAC"}

10
lib/constants/misc.js Normal file
View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeEnvs = void 0;
var NodeEnvs;
(function (NodeEnvs) {
NodeEnvs["Dev"] = "development";
NodeEnvs["Test"] = "test";
NodeEnvs["Production"] = "production";
})(NodeEnvs || (exports.NodeEnvs = NodeEnvs = {}));
//# sourceMappingURL=misc.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/constants/misc.ts"],"names":[],"mappings":";;;AAAA,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,+BAAmB,CAAA;IACnB,yBAAa,CAAA;IACb,qCAAyB,CAAA;AAC3B,CAAC,EAJW,QAAQ,wBAAR,QAAQ,QAInB"}

View File

@@ -0,0 +1,62 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const board_repo_1 = __importDefault(require("@src/repos/board.repo"));
class BoardController {
constructor() {
// Get all boards for a user
this.getBoardsByUserId = async (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
const userId = +req.params.userId;
const boards = await board_repo_1.default.getBoardsByUserId(userId);
return res.json({ boards });
};
// Get single board by userId and boardId
this.getBoardByUserId = async (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
const userId = +req.params.userId;
const boardId = +req.params.boardId;
const board = await board_repo_1.default.getBoardByUserId(userId, boardId);
return res.json({ board });
};
// Create board for a user
this.createBoard = async (req, res) => {
if (!req.body.name) {
return res.status(400).json({ error: 'Board name required' });
}
const userId = +req.params.userId;
const boardData = req.body;
const board = await board_repo_1.default.createBoard(userId, boardData);
return res.status(201).json({ board });
};
// Update board for a user
this.updateBoard = async (req, res) => {
if (!req.body.name) {
return res.status(400).json({ error: 'Board name required' });
}
const userId = +req.params.userId;
const boardId = +req.params.boardId;
const boardData = req.body;
const board = await board_repo_1.default.updateBoard(userId, boardId, boardData);
return res.json({ board });
};
// Delete board for a user
this.deleteBoard = async (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
const userId = +req.params.userId;
const boardId = +req.params.boardId;
await board_repo_1.default.deleteBoard(userId, boardId);
return res.status(204).end();
};
}
}
exports.default = new BoardController();
//# sourceMappingURL=board.controller.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"board.controller.js","sourceRoot":"","sources":["../../src/controllers/board.controller.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,64 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const task_repo_1 = __importDefault(require("@src/repos/task.repo"));
class TaskController {
constructor() {
// Get all tasks for a board
this.getTasksByBoardId = async (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
const boardId = +req.params.boardId;
const tasks = await task_repo_1.default.getTasksByBoardId(boardId);
return res.json({ tasks });
};
// Get single task by boardId and taskId
this.getTaskByBoardId = async (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
const boardId = +req.params.boardId;
const taskId = +req.params.taskId;
const task = await task_repo_1.default.getTaskByBoardId(boardId, taskId);
return res.json({ task });
};
// Create task for a board
this.createTask = async (req, res) => {
// Dummy form validation
if (!req.body.title) {
return res.status(400).json({ error: 'Task title required' });
}
const boardId = +req.params.boardId;
const taskData = req.body;
const task = await task_repo_1.default.createTask(boardId, taskData);
return res.status(201).json({ task });
};
// Update task for a board
this.updateTask = async (req, res) => {
// Dummy form validation
if (!req.body.title) {
return res.status(400).json({ error: 'Task title required' });
}
const boardId = +req.params.boardId;
const taskId = +req.params.taskId;
const taskData = req.body;
const task = await task_repo_1.default.updateTask(boardId, taskId, taskData);
return res.json({ task });
};
// Delete task for a board
this.deleteTask = async (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
const boardId = +req.params.boardId;
const taskId = +req.params.taskId;
await task_repo_1.default.deleteTask(boardId, taskId);
return res.status(204).end();
};
}
}
exports.default = new TaskController();
//# sourceMappingURL=task.controller.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"task.controller.js","sourceRoot":"","sources":["../../src/controllers/task.controller.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,31 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const user_repo_1 = __importDefault(require("@src/repos/user.repo"));
class UserController {
constructor() {
this.getAll = async (_, res) => {
const users = await user_repo_1.default.getAll();
return res.status(200).json({ users });
};
this.add = async (req, res) => {
const user = req.body.user;
await user_repo_1.default.add(user);
return res.status(201).end();
};
this.update = async (req, res) => {
const user = req.body.user;
await user_repo_1.default.update(user);
return res.status(200).end();
};
this.delete = async (req, res) => {
const id = +req.params.id;
await user_repo_1.default.delete(id);
return res.status(200).end();
};
}
}
exports.default = new UserController();
//# sourceMappingURL=user.controller.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"user.controller.js","sourceRoot":"","sources":["../../src/controllers/user.controller.ts"],"names":[],"mappings":";;;;;AACA,qEAA4C;AAG5C,MAAM,cAAc;IAApB;QACS,WAAM,GAAG,KAAK,EAAE,CAAU,EAAE,GAAa,EAAE,EAAE;YAClD,MAAM,KAAK,GAAG,MAAM,mBAAQ,CAAC,MAAM,EAAE,CAAC;YACtC,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACzC,CAAC,CAAC;QAEK,QAAG,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;YACjD,MAAM,IAAI,GAAU,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAClC,MAAM,mBAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACzB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/B,CAAC,CAAC;QAEK,WAAM,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;YACpD,MAAM,IAAI,GAAU,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAClC,MAAM,mBAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/B,CAAC,CAAC;QAEK,WAAM,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;YACpD,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,mBAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/B,CAAC,CAAC;IACJ,CAAC;CAAA;AAED,kBAAe,IAAI,cAAc,EAAE,CAAC"}

14
lib/index.js Normal file
View File

@@ -0,0 +1,14 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require("./pre-start"); // Must be the first import
const jet_logger_1 = __importDefault(require("jet-logger"));
const EnvVars_1 = __importDefault(require("@src/constants/EnvVars"));
const server_1 = __importDefault(require("./server"));
// **** Run **** //
const SERVER_START_MSG = ('Express server started on port: ' +
EnvVars_1.default.Port.toString());
server_1.default.listen(EnvVars_1.default.Port, () => jet_logger_1.default.info(SERVER_START_MSG));
//# sourceMappingURL=index.js.map

1
lib/index.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,uBAAqB,CAAC,2BAA2B;AACjD,4DAAgC;AAEhC,qEAA6C;AAC7C,sDAA8B;AAG9B,mBAAmB;AAEnB,MAAM,gBAAgB,GAAG,CAAC,kCAAkC;IAC1D,iBAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AAE3B,gBAAM,CAAC,MAAM,CAAC,iBAAO,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,oBAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC"}

48
lib/models/board.model.js Normal file
View File

@@ -0,0 +1,48 @@
"use strict";
// **** Variables **** //
Object.defineProperty(exports, "__esModule", { value: true });
const INVALID_CONSTRUCTOR_PARAM = 'nameOrObj arg must be a string or an object with the appropriate board keys.';
// **** Functions **** //
/**
* Create new Board.
*/
function new_(userId, name, description, createdAt, updatedAt, id) {
const now = new Date().toISOString();
return {
id: (id !== null && id !== void 0 ? id : -1),
userId: (userId !== null && userId !== void 0 ? userId : -1),
name: (name !== null && name !== void 0 ? name : ''),
description,
createdAt: (createdAt !== null && createdAt !== void 0 ? createdAt : now),
updatedAt: (updatedAt !== null && updatedAt !== void 0 ? updatedAt : now),
};
}
/**
* Get board instance from object.
*/
function from(param) {
if (!isBoard(param)) {
throw new Error(INVALID_CONSTRUCTOR_PARAM);
}
const p = param;
return new_(p.userId, p.name, p.description, p.createdAt, p.updatedAt, p.id);
}
/**
* See if the param meets criteria to be a board.
*/
function isBoard(arg) {
return (!!arg &&
typeof arg === 'object' &&
'id' in arg &&
'userId' in arg &&
'name' in arg &&
'createdAt' in arg &&
'updatedAt' in arg);
}
// **** Export default **** //
exports.default = {
new: new_,
from,
isBoard,
};
//# sourceMappingURL=board.model.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"board.model.js","sourceRoot":"","sources":["../../src/models/board.model.ts"],"names":[],"mappings":";AAAA,yBAAyB;;AAEzB,MAAM,yBAAyB,GAAG,8EAA8E,CAAC;AAajH,yBAAyB;AAEzB;;GAEG;AACH,SAAS,IAAI,CACZ,MAAe,EACf,IAAa,EACb,WAAoB,EACpB,SAAkB,EAClB,SAAkB,EAClB,EAAW;IAEX,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO;QACN,EAAE,EAAE,CAAC,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,CAAC,CAAC,CAAC;QACd,MAAM,EAAE,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,CAAC,CAAC,CAAC;QACtB,IAAI,EAAE,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC;QAClB,WAAW;QACX,SAAS,EAAE,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,GAAG,CAAC;QAC7B,SAAS,EAAE,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,GAAG,CAAC;KAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,IAAI,CAAC,KAAa;IAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,CAAC,GAAG,KAAe,CAAC;IAC1B,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,GAAY;IAC5B,OAAO,CACN,CAAC,CAAC,GAAG;QACL,OAAO,GAAG,KAAK,QAAQ;QACvB,IAAI,IAAI,GAAG;QACX,QAAQ,IAAI,GAAG;QACf,MAAM,IAAI,GAAG;QACb,WAAW,IAAI,GAAG;QAClB,WAAW,IAAI,GAAG,CAClB,CAAC;AACH,CAAC;AAED,8BAA8B;AAE9B,kBAAe;IACd,GAAG,EAAE,IAAI;IACT,IAAI;IACJ,OAAO;CACE,CAAC"}

50
lib/models/task.model.js Normal file
View File

@@ -0,0 +1,50 @@
"use strict";
// **** Variables **** //
Object.defineProperty(exports, "__esModule", { value: true });
const INVALID_CONSTRUCTOR_PARAM = 'titleOrObj arg must be a string or an object with the appropriate task keys.';
// **** Functions **** //
/**
* Create new Task.
*/
function new_(boardId, title, status, description, createdAt, updatedAt, id) {
const now = new Date().toISOString();
return {
id: (id !== null && id !== void 0 ? id : -1),
boardId: (boardId !== null && boardId !== void 0 ? boardId : -1),
title: (title !== null && title !== void 0 ? title : ''),
status: (status !== null && status !== void 0 ? status : 'todo'),
description,
createdAt: (createdAt !== null && createdAt !== void 0 ? createdAt : now),
updatedAt: (updatedAt !== null && updatedAt !== void 0 ? updatedAt : now),
};
}
/**
* Get task instance from object.
*/
function from(param) {
if (!isTask(param)) {
throw new Error(INVALID_CONSTRUCTOR_PARAM);
}
const p = param;
return new_(p.boardId, p.title, p.status, p.description, p.createdAt, p.updatedAt, p.id);
}
/**
* See if the param meets criteria to be a task.
*/
function isTask(arg) {
return (!!arg &&
typeof arg === 'object' &&
'id' in arg &&
'boardId' in arg &&
'title' in arg &&
'status' in arg &&
'createdAt' in arg &&
'updatedAt' in arg);
}
// **** Export default **** //
exports.default = {
new: new_,
from,
isTask,
};
//# sourceMappingURL=task.model.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"task.model.js","sourceRoot":"","sources":["../../src/models/task.model.ts"],"names":[],"mappings":";AAAA,yBAAyB;;AAEzB,MAAM,yBAAyB,GAAG,8EAA8E,CAAC;AAcjH,yBAAyB;AAEzB;;GAEG;AACH,SAAS,IAAI,CACZ,OAAgB,EAChB,KAAc,EACd,MAAwC,EACxC,WAAoB,EACpB,SAAkB,EAClB,SAAkB,EAClB,EAAW;IAEX,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO;QACN,EAAE,EAAE,CAAC,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,CAAC,CAAC,CAAC;QACd,OAAO,EAAE,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,CAAC,CAAC,CAAC;QACxB,KAAK,EAAE,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,CAAC;QACpB,MAAM,EAAE,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,MAAM,CAAC;QAC1B,WAAW;QACX,SAAS,EAAE,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,GAAG,CAAC;QAC7B,SAAS,EAAE,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,GAAG,CAAC;KAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,IAAI,CAAC,KAAa;IAC1B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,CAAC,GAAG,KAAc,CAAC;IACzB,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,GAAY;IAC3B,OAAO,CACN,CAAC,CAAC,GAAG;QACL,OAAO,GAAG,KAAK,QAAQ;QACvB,IAAI,IAAI,GAAG;QACX,SAAS,IAAI,GAAG;QAChB,OAAO,IAAI,GAAG;QACd,QAAQ,IAAI,GAAG;QACf,WAAW,IAAI,GAAG;QAClB,WAAW,IAAI,GAAG,CAClB,CAAC;AACH,CAAC;AAED,8BAA8B;AAE9B,kBAAe;IACd,GAAG,EAAE,IAAI;IACT,IAAI;IACJ,MAAM;CACG,CAAC"}

54
lib/models/user.model.js Normal file
View File

@@ -0,0 +1,54 @@
"use strict";
// **** Variables **** //
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserRoles = void 0;
const INVALID_CONSTRUCTOR_PARAM = 'nameOrObj arg must a string or an ' +
'object with the appropriate user keys.';
var UserRoles;
(function (UserRoles) {
UserRoles[UserRoles["Standard"] = 0] = "Standard";
UserRoles[UserRoles["Admin"] = 1] = "Admin";
})(UserRoles || (exports.UserRoles = UserRoles = {}));
// **** Functions **** //
/**
* Create new User.
*/
function new_(name, email, role, pwdHash, id) {
return {
id: (id !== null && id !== void 0 ? id : -1),
name: (name !== null && name !== void 0 ? name : ''),
email: (email !== null && email !== void 0 ? email : ''),
role: (role !== null && role !== void 0 ? role : UserRoles.Standard),
pwdHash: (pwdHash !== null && pwdHash !== void 0 ? pwdHash : ''),
};
}
/**
* Get user instance from object.
*/
function from(param) {
// Check is user
if (!isUser(param)) {
throw new Error(INVALID_CONSTRUCTOR_PARAM);
}
// Get user instance
const p = param;
return new_(p.name, p.email, p.role, p.pwdHash, p.id);
}
/**
* See if the param meets criteria to be a user.
*/
function isUser(arg) {
return (!!arg &&
typeof arg === 'object' &&
'id' in arg &&
'email' in arg &&
'name' in arg &&
'role' in arg);
}
// **** Export default **** //
exports.default = {
new: new_,
from,
isUser,
};
//# sourceMappingURL=user.model.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"user.model.js","sourceRoot":"","sources":["../../src/models/user.model.ts"],"names":[],"mappings":";AAAA,yBAAyB;;;AAEzB,MAAM,yBAAyB,GAAG,oCAAoC;IACpE,wCAAwC,CAAC;AAE3C,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,iDAAQ,CAAA;IACR,2CAAK,CAAA;AACP,CAAC,EAHW,SAAS,yBAAT,SAAS,QAGpB;AAqBD,yBAAyB;AAEzB;;GAEG;AACH,SAAS,IAAI,CACX,IAAa,EACb,KAAc,EACd,IAAgB,EAChB,OAAgB,EAChB,EAAW;IAEX,OAAO;QACL,EAAE,EAAE,CAAC,EAAE,aAAF,EAAE,cAAF,EAAE,GAAI,CAAC,CAAC,CAAC;QACd,IAAI,EAAE,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC;QAClB,KAAK,EAAE,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,CAAC;QACpB,IAAI,EAAE,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,SAAS,CAAC,QAAQ,CAAC;QAClC,OAAO,EAAE,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC;KACzB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,IAAI,CAAC,KAAa;IACzB,gBAAgB;IAChB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,oBAAoB;IACpB,MAAM,CAAC,GAAG,KAAc,CAAC;IACzB,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,GAAY;IAC1B,OAAO,CACL,CAAC,CAAC,GAAG;QACL,OAAO,GAAG,KAAK,QAAQ;QACvB,IAAI,IAAI,GAAG;QACX,OAAO,IAAI,GAAG;QACd,MAAM,IAAI,GAAG;QACb,MAAM,IAAI,GAAG,CACd,CAAC;AACJ,CAAC;AAGD,8BAA8B;AAE9B,kBAAe;IACb,GAAG,EAAE,IAAI;IACT,IAAI;IACJ,MAAM;CACE,CAAC"}

17
lib/other/classes.js Normal file
View File

@@ -0,0 +1,17 @@
"use strict";
/**
* Miscellaneous shared classes go here.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RouteError = void 0;
/**
* Error with status code and message
*/
class RouteError extends Error {
constructor(status, message) {
super(message);
this.status = status;
}
}
exports.RouteError = RouteError;
//# sourceMappingURL=classes.js.map

1
lib/other/classes.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"classes.js","sourceRoot":"","sources":["../../src/other/classes.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAKH;;GAEG;AACH,MAAa,UAAW,SAAQ,KAAK;IAEnC,YAAY,MAAuB,EAAE,OAAe;QAClD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAND,gCAMC"}

3
lib/other/types.js Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map

1
lib/other/types.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/other/types.ts"],"names":[],"mappings":""}

31
lib/pre-start.js Normal file
View File

@@ -0,0 +1,31 @@
"use strict";
/**
* Pre-start is where we want to place things that must run BEFORE the express
* server is started. This is useful for environment variables, command-line
* arguments, and cron-jobs.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// NOTE: DO NOT IMPORT ANY SOURCE CODE HERE
const path_1 = __importDefault(require("path"));
const dotenv_1 = __importDefault(require("dotenv"));
const ts_command_line_args_1 = require("ts-command-line-args");
// **** Setup **** //
// Command line arguments
const args = (0, ts_command_line_args_1.parse)({
env: {
type: String,
defaultValue: 'development',
alias: 'e',
},
});
// Set the env file
const result2 = dotenv_1.default.config({
path: path_1.default.join(__dirname, `../env/${args.env}.env`),
});
if (result2.error) {
throw result2.error;
}
//# sourceMappingURL=pre-start.js.map

1
lib/pre-start.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"pre-start.js","sourceRoot":"","sources":["../src/pre-start.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;AAEH,2CAA2C;AAC3C,gDAAwB;AACxB,oDAA4B;AAC5B,+DAA6C;AAU7C,qBAAqB;AAErB,yBAAyB;AACzB,MAAM,IAAI,GAAG,IAAA,4BAAK,EAAQ;IACxB,GAAG,EAAE;QACH,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,aAAa;QAC3B,KAAK,EAAE,GAAG;KACX;CACF,CAAC,CAAC;AAEH,mBAAmB;AACnB,MAAM,OAAO,GAAG,gBAAM,CAAC,MAAM,CAAC;IAC5B,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,IAAI,CAAC,GAAG,MAAM,CAAC;CACrD,CAAC,CAAC;AACH,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,MAAM,OAAO,CAAC,KAAK,CAAC;AACtB,CAAC"}

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Http = (() => {
// Setup request for json
var getOptions = (verb, data) => {
var options = {
dataType: 'json',
method: verb,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
};
if (data) {
options.body = JSON.stringify(data);
}
return options;
};
// Set Http methods
return {
get: (path) => fetch(path, getOptions('GET')),
post: (path, data) => fetch(path, getOptions('POST', data)),
put: (path, data) => fetch(path, getOptions('PUT', data)),
delete: (path) => fetch(path, getOptions('DELETE')),
};
})();
//# sourceMappingURL=http.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/public/scripts/http.js"],"names":[],"mappings":";;AAAA,IAAI,IAAI,GAAG,CAAC,GAAG,EAAE;IACf,yBAAyB;IACzB,IAAI,UAAU,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QAC9B,IAAI,OAAO,GAAG;YACZ,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;gBACP,QAAQ,EAAE,kBAAkB;gBAC5B,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC;QACF,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IACF,mBAAmB;IACnB,OAAO;QACL,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC3D,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACzD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;KACpD,CAAC;AACJ,CAAC,CAAC,EAAE,CAAC"}

154
lib/public/scripts/users.js Normal file
View File

@@ -0,0 +1,154 @@
"use strict";
// ***** Start **** //
Object.defineProperty(exports, "__esModule", { value: true });
displayUsers();
// ***** Fetch and display users **** //
/**
* Call api
*/
function displayUsers() {
Http
.get('/api/users/all')
.then(resp => resp.json())
.then((resp) => {
var allUsers = resp.users;
// Empty the anchor
var allUsersAnchor = document.getElementById('all-users-anchor');
allUsersAnchor.innerHTML = '';
// Append users to anchor
allUsers.forEach((user) => {
allUsersAnchor.innerHTML += getUserDisplayEle(user);
});
});
}
/**
* Get user display element
*/
function getUserDisplayEle(user) {
return (`<div class="user-display-ele">
<div class="normal-view">
<div>Name: ${user.name}</div>
<div>Email: ${user.email}</div>
<button class="edit-user-btn" data-user-id="${user.id}" data-user-role="${user.role}">
Edit
</button>
<button class="delete-user-btn" data-user-id="${user.id}">
Delete
</button>
</div>
<div class="edit-view">
<div>
Name: <input class="name-edit-input" value="${user.name}">
</div>
<div>
Email: <input class="email-edit-input" value="${user.email}">
</div>
<button class="submit-edit-btn" data-user-id="${user.id}">
Submit
</button>
<button class="cancel-edit-btn" data-user-id="${user.id}">
Cancel
</button>
</div>
</div>`);
}
// **** Add, Edit, and Delete Users **** //
// Setup event listener for button click
document.addEventListener('click', function (event) {
event.preventDefault();
var ele = event.target;
if (ele.matches('#add-user-btn')) {
addUser();
}
else if (ele.matches('.edit-user-btn')) {
showEditView(ele.parentNode.parentNode);
}
else if (ele.matches('.cancel-edit-btn')) {
cancelEdit(ele.parentNode.parentNode);
}
else if (ele.matches('.submit-edit-btn')) {
submitEdit(ele);
}
else if (ele.matches('.delete-user-btn')) {
deleteUser(ele);
}
else if (ele.matches('#logout-btn')) {
logoutUser();
}
}, false);
/**
* Add a new user.
*/
function addUser() {
var nameInput = document.getElementById('name-input');
var emailInput = document.getElementById('email-input');
var data = {
user: {
id: -1,
name: nameInput.value,
email: emailInput.value,
role: 0,
},
};
// Call api
Http
.post('/api/users/add', data)
.then(() => displayUsers());
}
/**
* Show edit view.
*/
function showEditView(userEle) {
var normalView = userEle.getElementsByClassName('normal-view')[0];
var editView = userEle.getElementsByClassName('edit-view')[0];
normalView.style.display = 'none';
editView.style.display = 'block';
}
/**
* Cancel edit.
*/
function cancelEdit(userEle) {
var normalView = userEle.getElementsByClassName('normal-view')[0];
var editView = userEle.getElementsByClassName('edit-view')[0];
normalView.style.display = 'block';
editView.style.display = 'none';
}
/**
* Submit edit.
*/
function submitEdit(ele) {
var userEle = ele.parentNode.parentNode;
var nameInput = userEle.getElementsByClassName('name-edit-input')[0];
var emailInput = userEle.getElementsByClassName('email-edit-input')[0];
var id = ele.getAttribute('data-user-id');
var role = ele.getAttribute('data-user-role');
var data = {
user: {
id: Number(id),
name: nameInput.value,
email: emailInput.value,
role: Number(role),
},
};
Http
.put('/api/users/update', data)
.then(() => displayUsers());
}
/**
* Delete a user
*/
function deleteUser(ele) {
var id = ele.getAttribute('data-user-id');
Http
.delete('/api/users/delete/' + id)
.then(() => displayUsers());
}
// **** Logout **** //
function logoutUser() {
Http
.get('/api/auth/logout')
.then(() => window.location.href = '/');
}
//# sourceMappingURL=users.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../../src/public/scripts/users.js"],"names":[],"mappings":"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"}

52
lib/repos/BoardRepo.js Normal file
View File

@@ -0,0 +1,52 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const MockOrm_1 = __importDefault(require("./MockOrm"));
async function getBoardsByUserId(userId) {
const db = await MockOrm_1.default.openDb();
return db.boards.filter((board) => board.userId === userId);
}
async function getBoardByUserId(userId, boardId) {
const db = await MockOrm_1.default.openDb();
return db.boards.find((board) => board.userId === userId && board.id === boardId) || null;
}
async function createBoard(userId, board) {
const db = await MockOrm_1.default.openDb();
board.id = Date.now();
board.userId = userId;
board.createdAt = new Date().toISOString();
board.updatedAt = board.createdAt;
db.boards.push(board);
await MockOrm_1.default.saveDb(db);
return board;
}
async function updateBoard(userId, boardId, boardData) {
const db = await MockOrm_1.default.openDb();
const board = db.boards.find((b) => b.userId === userId && b.id === boardId);
if (board) {
Object.assign(board, boardData, { updatedAt: new Date().toISOString() });
await MockOrm_1.default.saveDb(db);
return board;
}
return null;
}
async function deleteBoard(userId, boardId) {
const db = await MockOrm_1.default.openDb();
const idx = db.boards.findIndex((b) => b.userId === userId && b.id === boardId);
if (idx !== -1) {
db.boards.splice(idx, 1);
await MockOrm_1.default.saveDb(db);
return true;
}
return false;
}
exports.default = {
getBoardsByUserId,
getBoardByUserId,
createBoard,
updateBoard,
deleteBoard,
};
//# sourceMappingURL=BoardRepo.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BoardRepo.js","sourceRoot":"","sources":["../../src/repos/BoardRepo.ts"],"names":[],"mappings":";;;;;AACA,wDAA4B;AAE5B,KAAK,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACrE,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,MAAc,EAAE,OAAe;IAC9D,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC;AACnG,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,KAAa;IACvD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACd,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,OAAe,EAAE,SAA0B;IACrF,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACrF,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACzE,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,OAAe;IACzD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACxF,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QAChB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,kBAAe;IACd,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,WAAW;IACX,WAAW;CACX,CAAC"}

27
lib/repos/MockOrm.js Normal file
View File

@@ -0,0 +1,27 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsonfile_1 = __importDefault(require("jsonfile"));
// **** Variables **** //
const DB_FILE_NAME = 'database.json';
// **** Functions **** //
/**
* Fetch the json from the file.
*/
function openDb() {
return jsonfile_1.default.readFile(__dirname + '/' + DB_FILE_NAME);
}
/**
* Update the file.
*/
function saveDb(db) {
return jsonfile_1.default.writeFile((__dirname + '/' + DB_FILE_NAME), db);
}
// **** Export default **** //
exports.default = {
openDb,
saveDb,
};
//# sourceMappingURL=MockOrm.js.map

1
lib/repos/MockOrm.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"MockOrm.js","sourceRoot":"","sources":["../../src/repos/MockOrm.ts"],"names":[],"mappings":";;;;;AAEA,wDAAgC;AAOhC,yBAAyB;AAEzB,MAAM,YAAY,GAAG,eAAe,CAAC;AAYrC,yBAAyB;AAEzB;;GAEG;AACH,SAAS,MAAM;IACb,OAAO,kBAAQ,CAAC,QAAQ,CAAC,SAAS,GAAG,GAAG,GAAG,YAAY,CAAiB,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,EAAO;IACrB,OAAO,kBAAQ,CAAC,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;AAClE,CAAC;AAGD,8BAA8B;AAE9B,kBAAe;IACb,MAAM;IACN,MAAM;CACE,CAAC"}

52
lib/repos/TaskRepo.js Normal file
View File

@@ -0,0 +1,52 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const MockOrm_1 = __importDefault(require("./MockOrm"));
async function getTasksByBoardId(boardId) {
const db = await MockOrm_1.default.openDb();
return db.tasks.filter((task) => task.boardId === boardId);
}
async function getTaskByBoardId(boardId, taskId) {
const db = await MockOrm_1.default.openDb();
return db.tasks.find((task) => task.boardId === boardId && task.id === taskId) || null;
}
async function createTask(boardId, task) {
const db = await MockOrm_1.default.openDb();
task.id = Date.now();
task.boardId = boardId;
task.createdAt = new Date().toISOString();
task.updatedAt = task.createdAt;
db.tasks.push(task);
await MockOrm_1.default.saveDb(db);
return task;
}
async function updateTask(boardId, taskId, taskData) {
const db = await MockOrm_1.default.openDb();
const task = db.tasks.find((t) => t.boardId === boardId && t.id === taskId);
if (task) {
Object.assign(task, taskData, { updatedAt: new Date().toISOString() });
await MockOrm_1.default.saveDb(db);
return task;
}
return null;
}
async function deleteTask(boardId, taskId) {
const db = await MockOrm_1.default.openDb();
const idx = db.tasks.findIndex((t) => t.boardId === boardId && t.id === taskId);
if (idx !== -1) {
db.tasks.splice(idx, 1);
await MockOrm_1.default.saveDb(db);
return true;
}
return false;
}
exports.default = {
getTasksByBoardId,
getTaskByBoardId,
createTask,
updateTask,
deleteTask,
};
//# sourceMappingURL=TaskRepo.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TaskRepo.js","sourceRoot":"","sources":["../../src/repos/TaskRepo.ts"],"names":[],"mappings":";;;;;AACA,wDAA4B;AAE5B,KAAK,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAW,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAe,EAAE,MAAc;IAC9D,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAW,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC;AAC/F,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,IAAW;IACrD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAChC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,MAAc,EAAE,QAAwB;IAClF,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACnF,IAAI,IAAI,EAAE,CAAC;QACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACvE,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,MAAc;IACxD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACvF,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QAChB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACxB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,kBAAe;IACd,iBAAiB;IACjB,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,UAAU;CACV,CAAC"}

52
lib/repos/board.repo.js Normal file
View File

@@ -0,0 +1,52 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const MockOrm_1 = __importDefault(require("./MockOrm"));
async function getBoardsByUserId(userId) {
const db = await MockOrm_1.default.openDb();
return db.boards.filter((board) => board.userId === userId);
}
async function getBoardByUserId(userId, boardId) {
const db = await MockOrm_1.default.openDb();
return db.boards.find((board) => board.userId === userId && board.id === boardId) || null;
}
async function createBoard(userId, board) {
const db = await MockOrm_1.default.openDb();
board.id = Date.now();
board.userId = userId;
board.createdAt = new Date().toISOString();
board.updatedAt = board.createdAt;
db.boards.push(board);
await MockOrm_1.default.saveDb(db);
return board;
}
async function updateBoard(userId, boardId, boardData) {
const db = await MockOrm_1.default.openDb();
const board = db.boards.find((b) => b.userId === userId && b.id === boardId);
if (board) {
Object.assign(board, boardData, { updatedAt: new Date().toISOString() });
await MockOrm_1.default.saveDb(db);
return board;
}
return null;
}
async function deleteBoard(userId, boardId) {
const db = await MockOrm_1.default.openDb();
const idx = db.boards.findIndex((b) => b.userId === userId && b.id === boardId);
if (idx !== -1) {
db.boards.splice(idx, 1);
await MockOrm_1.default.saveDb(db);
return true;
}
return false;
}
exports.default = {
getBoardsByUserId,
getBoardByUserId,
createBoard,
updateBoard,
deleteBoard,
};
//# sourceMappingURL=board.repo.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"board.repo.js","sourceRoot":"","sources":["../../src/repos/board.repo.ts"],"names":[],"mappings":";;;;;AACA,wDAA4B;AAE5B,KAAK,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACrE,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,MAAc,EAAE,OAAe;IAC9D,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC;AACnG,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,KAAa;IACvD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACtB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACd,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,OAAe,EAAE,SAA0B;IACrF,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACrF,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACzE,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,MAAc,EAAE,OAAe;IACzD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACxF,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QAChB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,kBAAe;IACd,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,WAAW;IACX,WAAW;CACX,CAAC"}

52
lib/repos/task.repo.js Normal file
View File

@@ -0,0 +1,52 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const MockOrm_1 = __importDefault(require("./MockOrm"));
async function getTasksByBoardId(boardId) {
const db = await MockOrm_1.default.openDb();
return db.tasks.filter((task) => task.boardId === boardId);
}
async function getTaskByBoardId(boardId, taskId) {
const db = await MockOrm_1.default.openDb();
return db.tasks.find((task) => task.boardId === boardId && task.id === taskId) || null;
}
async function createTask(boardId, task) {
const db = await MockOrm_1.default.openDb();
task.id = Date.now();
task.boardId = boardId;
task.createdAt = new Date().toISOString();
task.updatedAt = task.createdAt;
db.tasks.push(task);
await MockOrm_1.default.saveDb(db);
return task;
}
async function updateTask(boardId, taskId, taskData) {
const db = await MockOrm_1.default.openDb();
const task = db.tasks.find((t) => t.boardId === boardId && t.id === taskId);
if (task) {
Object.assign(task, taskData, { updatedAt: new Date().toISOString() });
await MockOrm_1.default.saveDb(db);
return task;
}
return null;
}
async function deleteTask(boardId, taskId) {
const db = await MockOrm_1.default.openDb();
const idx = db.tasks.findIndex((t) => t.boardId === boardId && t.id === taskId);
if (idx !== -1) {
db.tasks.splice(idx, 1);
await MockOrm_1.default.saveDb(db);
return true;
}
return false;
}
exports.default = {
getTasksByBoardId,
getTaskByBoardId,
createTask,
updateTask,
deleteTask,
};
//# sourceMappingURL=task.repo.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"task.repo.js","sourceRoot":"","sources":["../../src/repos/task.repo.ts"],"names":[],"mappings":";;;;;AACA,wDAA4B;AAE5B,KAAK,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAW,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAe,EAAE,MAAc;IAC9D,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAW,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC;AAC/F,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,IAAW;IACrD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAChC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrB,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,MAAc,EAAE,QAAwB;IAClF,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACnF,IAAI,IAAI,EAAE,CAAC;QACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACvE,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,MAAc;IACxD,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACvF,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QAChB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACxB,MAAM,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,kBAAe;IACd,iBAAiB;IACjB,gBAAgB;IAChB,UAAU;IACV,UAAU;IACV,UAAU;CACV,CAAC"}

82
lib/repos/user.repo.js Normal file
View File

@@ -0,0 +1,82 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const misc_1 = require("@src/util/misc");
const MockOrm_1 = __importDefault(require("./MockOrm"));
// **** Functions **** //
/**
* Get one user.
*/
async function getOne(email) {
const db = await MockOrm_1.default.openDb();
for (const user of db.users) {
if (user.email === email) {
return user;
}
}
return null;
}
/**
* See if a user with the given id exists.
*/
async function persists(id) {
const db = await MockOrm_1.default.openDb();
for (const user of db.users) {
if (user.id === id) {
return true;
}
}
return false;
}
/**
* Get all users.
*/
async function getAll() {
const db = await MockOrm_1.default.openDb();
return db.users;
}
/**
* Add one user.
*/
async function add(user) {
const db = await MockOrm_1.default.openDb();
user.id = (0, misc_1.getRandomInt)();
db.users.push(user);
return MockOrm_1.default.saveDb(db);
}
/**
* Update a user.
*/
async function update(user) {
const db = await MockOrm_1.default.openDb();
for (let i = 0; i < db.users.length; i++) {
if (db.users[i].id === user.id) {
db.users[i] = user;
return MockOrm_1.default.saveDb(db);
}
}
}
/**
* Delete one user.
*/
async function delete_(id) {
const db = await MockOrm_1.default.openDb();
for (let i = 0; i < db.users.length; i++) {
if (db.users[i].id === id) {
db.users.splice(i, 1);
return MockOrm_1.default.saveDb(db);
}
}
}
// **** Export default **** //
exports.default = {
getOne,
persists,
getAll,
add,
update,
delete: delete_,
};
//# sourceMappingURL=user.repo.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"user.repo.js","sourceRoot":"","sources":["../../src/repos/user.repo.ts"],"names":[],"mappings":";;;;;AACA,yCAA8C;AAC9C,wDAA4B;AAG5B,yBAAyB;AAEzB;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,KAAa;IACjC,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,QAAQ,CAAC,EAAU;IAChC,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,MAAM;IACnB,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,CAAC,KAAK,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,GAAG,CAAC,IAAW;IAC5B,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,GAAG,IAAA,mBAAY,GAAE,CAAC;IACzB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,OAAO,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,IAAW;IAC/B,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/B,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACnB,OAAO,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CAAC,EAAU;IAC/B,MAAM,EAAE,GAAG,MAAM,iBAAG,CAAC,MAAM,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YAC1B,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACtB,OAAO,iBAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;AACH,CAAC;AAGD,8BAA8B;AAE9B,kBAAe;IACb,MAAM;IACN,QAAQ;IACR,MAAM;IACN,GAAG;IACH,MAAM;IACN,MAAM,EAAE,OAAO;CACP,CAAC"}

24
lib/routes/api.js Normal file
View File

@@ -0,0 +1,24 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const jet_validator_1 = __importDefault(require("jet-validator"));
const Paths_1 = __importDefault(require("./constants/Paths"));
const user_model_1 = __importDefault(require("@src/models/user.model"));
const user_controller_1 = __importDefault(require("@src/controllers/user.controller"));
// **** Variables **** //
const apiRouter = (0, express_1.Router)(), validate = (0, jet_validator_1.default)();
// ** Add UserRouter ** //
const userRouter = (0, express_1.Router)();
// Get all users
userRouter.get(Paths_1.default.Users.Get, user_controller_1.default.getAll.bind(user_controller_1.default));
userRouter.post(Paths_1.default.Users.Add, validate(['user', user_model_1.default.isUser]), user_controller_1.default.add.bind(user_controller_1.default));
userRouter.put(Paths_1.default.Users.Update, validate(['user', user_model_1.default.isUser]), user_controller_1.default.update.bind(user_controller_1.default));
userRouter.delete(Paths_1.default.Users.Delete, validate(['id', 'number', 'params']), user_controller_1.default.delete.bind(user_controller_1.default));
// Add UserRouter
apiRouter.use(Paths_1.default.Users.Base, userRouter);
// **** Export default **** //
exports.default = apiRouter;
//# sourceMappingURL=api.js.map

1
lib/routes/api.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/routes/api.ts"],"names":[],"mappings":";;;;;AAAA,qCAAiC;AACjC,kEAAyC;AAEzC,8DAAsC;AACtC,wEAA0C;AAC1C,uFAA8D;AAG9D,yBAAyB;AAEzB,MAAM,SAAS,GAAG,IAAA,gBAAM,GAAE,EACxB,QAAQ,GAAG,IAAA,uBAAY,GAAE,CAAC;AAG5B,0BAA0B;AAE1B,MAAM,UAAU,GAAG,IAAA,gBAAM,GAAE,CAAC;AAE5B,gBAAgB;AAChB,UAAU,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,GAAG,EAAE,yBAAc,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAc,CAAC,CAAC,CAAC;AAC5E,UAAU,CAAC,IAAI,CACb,eAAK,CAAC,KAAK,CAAC,GAAG,EACf,QAAQ,CAAC,CAAC,MAAM,EAAE,oBAAI,CAAC,MAAM,CAAC,CAAC,EAC/B,yBAAc,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAc,CAAC,CACxC,CAAC;AACF,UAAU,CAAC,GAAG,CACZ,eAAK,CAAC,KAAK,CAAC,MAAM,EAClB,QAAQ,CAAC,CAAC,MAAM,EAAE,oBAAI,CAAC,MAAM,CAAC,CAAC,EAC/B,yBAAc,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAc,CAAC,CAC3C,CAAC;AACF,UAAU,CAAC,MAAM,CACf,eAAK,CAAC,KAAK,CAAC,MAAM,EAClB,QAAQ,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EACpC,yBAAc,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAc,CAAC,CAC3C,CAAC;AAEF,iBAAiB;AACjB,SAAS,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAG5C,8BAA8B;AAE9B,kBAAe,SAAS,CAAC"}

15
lib/routes/board.route.js Normal file
View File

@@ -0,0 +1,15 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const board_controller_1 = __importDefault(require("../controllers/board.controller"));
const router = (0, express_1.Router)();
router.get('/user/:userId', board_controller_1.default.getBoardsByUserId);
router.get('/user/:userId/:boardId', board_controller_1.default.getBoardByUserId);
router.post('/user/:userId', board_controller_1.default.createBoard);
router.put('/user/:userId/:boardId', board_controller_1.default.updateBoard);
router.delete('/user/:userId/:boardId', board_controller_1.default.deleteBoard);
exports.default = router;
//# sourceMappingURL=board.route.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"board.route.js","sourceRoot":"","sources":["../../src/routes/board.route.ts"],"names":[],"mappings":";;;;;AACA,qCAAiC;AACjC,uFAA8D;AAE9D,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,0BAAe,CAAC,iBAAiB,CAAC,CAAC;AAC/D,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,0BAAe,CAAC,gBAAgB,CAAC,CAAC;AACvE,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,0BAAe,CAAC,WAAW,CAAC,CAAC;AAC1D,MAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,0BAAe,CAAC,WAAW,CAAC,CAAC;AAClE,MAAM,CAAC,MAAM,CAAC,wBAAwB,EAAE,0BAAe,CAAC,WAAW,CAAC,CAAC;AAErE,kBAAe,MAAM,CAAC"}

View File

@@ -0,0 +1,30 @@
"use strict";
/**
* Convert paths to full paths.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Paths_1 = __importDefault(require("./Paths"));
/**
* The recursive function.
*/
function getFullPaths(parent, baseUrl) {
const url = (baseUrl + parent.Base), keys = Object.keys(parent), retVal = { Base: url };
// Iterate keys
for (const key of keys) {
const pval = parent[key];
if (key !== 'Base' && typeof pval === 'string') {
retVal[key] = (url + pval);
}
else if (typeof pval === 'object') {
retVal[key] = getFullPaths(pval, url);
}
}
// Return
return retVal;
}
// **** Export default **** //
exports.default = getFullPaths(Paths_1.default, '');
//# sourceMappingURL=FullPaths.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"FullPaths.js","sourceRoot":"","sources":["../../../src/routes/constants/FullPaths.ts"],"names":[],"mappings":";AACA;;GAEG;;;;;AAEH,oDAAwC;AAQxC;;GAEG;AACH,SAAS,YAAY,CACnB,MAAgB,EAChB,OAAe;IAEf,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,EACjC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAC1B,MAAM,GAAa,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACnC,eAAe;IACf,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,GAAG,KAAK,MAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IACD,SAAS;IACT,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,8BAA8B;AAE9B,kBAAe,YAAY,CAAC,eAAK,EAAE,EAAE,CAAW,CAAC"}

View File

@@ -0,0 +1,17 @@
"use strict";
/**
* Express router paths go here.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const Paths = {
Base: '/api',
Users: {
Base: '/users',
Get: '/all',
Add: '/add',
Update: '/update',
Delete: '/delete/:id',
},
};
exports.default = Paths;
//# sourceMappingURL=Paths.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Paths.js","sourceRoot":"","sources":["../../../src/routes/constants/Paths.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAKH,MAAM,KAAK,GAAG;IACZ,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE,MAAM;QACX,GAAG,EAAE,MAAM;QACX,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,aAAa;KACtB;CACF,CAAC;AAMF,kBAAe,KAAe,CAAC"}

15
lib/routes/task.route.js Normal file
View File

@@ -0,0 +1,15 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const task_controller_1 = __importDefault(require("../controllers/task.controller"));
const router = (0, express_1.Router)();
router.get('/board/:boardId', task_controller_1.default.getTasksByBoardId);
router.get('/board/:boardId/:taskId', task_controller_1.default.getTaskByBoardId);
router.post('/board/:boardId', task_controller_1.default.createTask);
router.put('/board/:boardId/:taskId', task_controller_1.default.updateTask);
router.delete('/board/:boardId/:taskId', task_controller_1.default.deleteTask);
exports.default = router;
//# sourceMappingURL=task.route.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"task.route.js","sourceRoot":"","sources":["../../src/routes/task.route.ts"],"names":[],"mappings":";;;;;AACA,qCAAiC;AACjC,qFAA4D;AAE5D,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,yBAAc,CAAC,iBAAiB,CAAC,CAAC;AAChE,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,yBAAc,CAAC,gBAAgB,CAAC,CAAC;AACvE,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,yBAAc,CAAC,UAAU,CAAC,CAAC;AAC1D,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,yBAAc,CAAC,UAAU,CAAC,CAAC;AACjE,MAAM,CAAC,MAAM,CAAC,yBAAyB,EAAE,yBAAc,CAAC,UAAU,CAAC,CAAC;AAEpE,kBAAe,MAAM,CAAC"}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=misc.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../../../src/routes/types/express/misc.ts"],"names":[],"mappings":""}

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/routes/types/types.ts"],"names":[],"mappings":""}

14
lib/routes/user.route.js Normal file
View File

@@ -0,0 +1,14 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const user_controller_1 = __importDefault(require("../controllers/user.controller"));
const router = (0, express_1.Router)();
router.get('/', user_controller_1.default.getAll);
router.post('/', user_controller_1.default.add);
router.put('/', user_controller_1.default.update);
router.delete('/:id', user_controller_1.default.delete);
exports.default = router;
//# sourceMappingURL=user.route.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"user.route.js","sourceRoot":"","sources":["../../src/routes/user.route.ts"],"names":[],"mappings":";;;;;AAAA,qCAAiC;AACjC,qFAA4D;AAE5D,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAExB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,yBAAc,CAAC,MAAM,CAAC,CAAC;AACvC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,yBAAc,CAAC,GAAG,CAAC,CAAC;AACrC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,yBAAc,CAAC,MAAM,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAc,CAAC,MAAM,CAAC,CAAC;AAE7C,kBAAe,MAAM,CAAC"}

69
lib/server.js Normal file
View File

@@ -0,0 +1,69 @@
"use strict";
/**
* Setup express server.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cookie_parser_1 = __importDefault(require("cookie-parser"));
const morgan_1 = __importDefault(require("morgan"));
const path_1 = __importDefault(require("path"));
const helmet_1 = __importDefault(require("helmet"));
const express_1 = __importDefault(require("express"));
const jet_logger_1 = __importDefault(require("jet-logger"));
require("express-async-errors");
const api_1 = __importDefault(require("@src/routes/api"));
const Paths_1 = __importDefault(require("@src/routes/constants/Paths"));
const EnvVars_1 = __importDefault(require("@src/constants/EnvVars"));
const HttpStatusCodes_1 = __importDefault(require("@src/constants/HttpStatusCodes"));
const misc_1 = require("@src/constants/misc");
const classes_1 = require("@src/other/classes");
// **** Variables **** //
const app = (0, express_1.default)();
// **** Setup **** //
// Basic middleware
app.use(express_1.default.json());
app.use(express_1.default.urlencoded({ extended: true }));
app.use((0, cookie_parser_1.default)(EnvVars_1.default.CookieProps.Secret));
// Show routes called in console during development
if (EnvVars_1.default.NodeEnv === misc_1.NodeEnvs.Dev) {
app.use((0, morgan_1.default)('dev'));
}
// Security
if (EnvVars_1.default.NodeEnv === misc_1.NodeEnvs.Production) {
app.use((0, helmet_1.default)());
}
// Add APIs, must be after middleware
app.use(Paths_1.default.Base, api_1.default);
// Add error handler
app.use((err, _, res,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
next) => {
if (EnvVars_1.default.NodeEnv !== misc_1.NodeEnvs.Test) {
jet_logger_1.default.err(err, true);
}
let status = HttpStatusCodes_1.default.BAD_REQUEST;
if (err instanceof classes_1.RouteError) {
status = err.status;
}
return res.status(status).json({ error: err.message });
});
// ** Front-End Content ** //
// Set views directory (html)
const viewsDir = path_1.default.join(__dirname, 'views');
app.set('views', viewsDir);
// Set static directory (js and css).
const staticDir = path_1.default.join(__dirname, 'public');
app.use(express_1.default.static(staticDir));
// Nav to users pg by default
app.get('/', (_, res) => {
return res.redirect('/users');
});
// Redirect to login if not logged in.
app.get('/users', (_, res) => {
return res.sendFile('users.html', { root: viewsDir });
});
// **** Export default **** //
exports.default = app;
//# sourceMappingURL=server.js.map

1
lib/server.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;AAEH,kEAAyC;AACzC,oDAA4B;AAC5B,gDAAwB;AACxB,oDAA4B;AAC5B,sDAAmE;AACnE,4DAAgC;AAEhC,gCAA8B;AAE9B,0DAAyC;AACzC,wEAAgD;AAEhD,qEAA6C;AAC7C,qFAA6D;AAE7D,8CAA+C;AAC/C,gDAAgD;AAGhD,yBAAyB;AAEzB,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;AAGtB,qBAAqB;AAErB,mBAAmB;AACnB,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACxB,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC;AAC9C,GAAG,CAAC,GAAG,CAAC,IAAA,uBAAY,EAAC,iBAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AAElD,mDAAmD;AACnD,IAAI,iBAAO,CAAC,OAAO,KAAK,eAAQ,CAAC,GAAG,EAAE,CAAC;IACrC,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,EAAC,KAAK,CAAC,CAAC,CAAC;AACzB,CAAC;AAED,WAAW;AACX,IAAI,iBAAO,CAAC,OAAO,KAAK,eAAQ,CAAC,UAAU,EAAE,CAAC;IAC5C,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,GAAE,CAAC,CAAC;AACpB,CAAC;AAED,qCAAqC;AACrC,GAAG,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,EAAE,aAAU,CAAC,CAAC;AAEhC,oBAAoB;AACpB,GAAG,CAAC,GAAG,CAAC,CACN,GAAU,EACV,CAAU,EACV,GAAa;AACb,6DAA6D;AAC7D,IAAkB,EAClB,EAAE;IACF,IAAI,iBAAO,CAAC,OAAO,KAAK,eAAQ,CAAC,IAAI,EAAE,CAAC;QACtC,oBAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,MAAM,GAAG,yBAAe,CAAC,WAAW,CAAC;IACzC,IAAI,GAAG,YAAY,oBAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IACtB,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAGH,6BAA6B;AAE7B,6BAA6B;AAC7B,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC/C,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAE3B,qCAAqC;AACrC,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACjD,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAEnC,6BAA6B;AAC7B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAU,EAAE,GAAa,EAAE,EAAE;IACzC,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,sCAAsC;AACtC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAU,EAAE,GAAa,EAAE,EAAE;IAC9C,OAAO,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAGH,8BAA8B;AAE9B,kBAAe,GAAG,CAAC"}

View File

@@ -0,0 +1,45 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Errors = void 0;
const user_repo_1 = __importDefault(require("@src/repos/user.repo"));
const PwdUtil_1 = __importDefault(require("@src/util/PwdUtil"));
const misc_1 = require("@src/util/misc");
const HttpStatusCodes_1 = __importDefault(require("@src/constants/HttpStatusCodes"));
const classes_1 = require("@src/other/classes");
// **** Variables **** //
// Errors
exports.Errors = {
Unauth: 'Unauthorized',
EmailNotFound(email) {
return `User with email "${email}" not found`;
},
};
// **** Functions **** //
/**
* Login a user.
*/
async function login(email, password) {
var _a;
// Fetch user
const user = await user_repo_1.default.getOne(email);
if (!user) {
throw new classes_1.RouteError(HttpStatusCodes_1.default.UNAUTHORIZED, exports.Errors.EmailNotFound(email));
}
// Check password
const hash = ((_a = user.pwdHash) !== null && _a !== void 0 ? _a : ''), pwdPassed = await PwdUtil_1.default.compare(password, hash);
if (!pwdPassed) {
// If password failed, wait 500ms this will increase security
await (0, misc_1.tick)(500);
throw new classes_1.RouteError(HttpStatusCodes_1.default.UNAUTHORIZED, exports.Errors.Unauth);
}
// Return
return user;
}
// **** Export default **** //
exports.default = {
login,
};
//# sourceMappingURL=AuthService.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AuthService.js","sourceRoot":"","sources":["../../src/services/AuthService.ts"],"names":[],"mappings":";;;;;;AAAA,qEAA4C;AAE5C,gEAAwC;AACxC,yCAAsC;AAEtC,qFAA6D;AAC7D,gDAAgD;AAIhD,yBAAyB;AAEzB,SAAS;AACI,QAAA,MAAM,GAAG;IACpB,MAAM,EAAE,cAAc;IACtB,aAAa,CAAC,KAAa;QACzB,OAAO,oBAAoB,KAAK,aAAa,CAAC;IAChD,CAAC;CACO,CAAC;AAGX,yBAAyB;AAEzB;;GAEG;AACH,KAAK,UAAU,KAAK,CAAC,KAAa,EAAE,QAAgB;;IAClD,aAAa;IACb,MAAM,IAAI,GAAG,MAAM,mBAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,oBAAU,CAClB,yBAAe,CAAC,YAAY,EAC5B,cAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAC5B,CAAC;IACJ,CAAC;IACD,iBAAiB;IACjB,MAAM,IAAI,GAAG,CAAC,MAAA,IAAI,CAAC,OAAO,mCAAI,EAAE,CAAC,EAC/B,SAAS,GAAG,MAAM,iBAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,6DAA6D;QAC7D,MAAM,IAAA,WAAI,EAAC,GAAG,CAAC,CAAC;QAChB,MAAM,IAAI,oBAAU,CAClB,yBAAe,CAAC,YAAY,EAC5B,cAAM,CAAC,MAAM,CACd,CAAC;IACJ,CAAC;IACD,SAAS;IACT,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,8BAA8B;AAE9B,kBAAe;IACb,KAAK;CACG,CAAC"}

View File

@@ -0,0 +1,54 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.USER_NOT_FOUND_ERR = void 0;
const user_repo_1 = __importDefault(require("@src/repos/user.repo"));
const classes_1 = require("@src/other/classes");
const HttpStatusCodes_1 = __importDefault(require("@src/constants/HttpStatusCodes"));
// **** Variables **** //
exports.USER_NOT_FOUND_ERR = 'User not found';
// **** Functions **** //
/**
* Get all users.
*/
function getAll() {
return user_repo_1.default.getAll();
}
/**
* Add one user.
*/
function addOne(user) {
return user_repo_1.default.add(user);
}
/**
* Update one user.
*/
async function updateOne(user) {
const persists = await user_repo_1.default.persists(user.id);
if (!persists) {
throw new classes_1.RouteError(HttpStatusCodes_1.default.NOT_FOUND, exports.USER_NOT_FOUND_ERR);
}
// Return user
return user_repo_1.default.update(user);
}
/**
* Delete a user by their id.
*/
async function _delete(id) {
const persists = await user_repo_1.default.persists(id);
if (!persists) {
throw new classes_1.RouteError(HttpStatusCodes_1.default.NOT_FOUND, exports.USER_NOT_FOUND_ERR);
}
// Delete user
return user_repo_1.default.delete(id);
}
// **** Export default **** //
exports.default = {
getAll,
addOne,
updateOne,
delete: _delete,
};
//# sourceMappingURL=UserService.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"UserService.js","sourceRoot":"","sources":["../../src/services/UserService.ts"],"names":[],"mappings":";;;;;;AAAA,qEAA4C;AAE5C,gDAAgD;AAChD,qFAA6D;AAG7D,yBAAyB;AAEZ,QAAA,kBAAkB,GAAG,gBAAgB,CAAC;AAGnD,yBAAyB;AAEzB;;GAEG;AACH,SAAS,MAAM;IACb,OAAO,mBAAQ,CAAC,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,SAAS,MAAM,CAAC,IAAW;IACzB,OAAO,mBAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,SAAS,CAAC,IAAW;IAClC,MAAM,QAAQ,GAAG,MAAM,mBAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,oBAAU,CAClB,yBAAe,CAAC,SAAS,EACzB,0BAAkB,CACnB,CAAC;IACJ,CAAC;IACD,cAAc;IACd,OAAO,mBAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,OAAO,CAAC,EAAU;IAC/B,MAAM,QAAQ,GAAG,MAAM,mBAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,oBAAU,CAClB,yBAAe,CAAC,SAAS,EACzB,0BAAkB,CACnB,CAAC;IACJ,CAAC;IACD,cAAc;IACd,OAAO,mBAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC7B,CAAC;AAGD,8BAA8B;AAE9B,kBAAe;IACb,MAAM;IACN,MAAM;IACN,SAAS;IACT,MAAM,EAAE,OAAO;CACP,CAAC"}

34
lib/util/PwdUtil.js Normal file
View File

@@ -0,0 +1,34 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bcrypt_1 = __importDefault(require("bcrypt"));
// **** Variables **** //
const SALT_ROUNDS = 12;
// **** Functions **** //
/**
* Get a hash from the password.
*/
function getHash(pwd) {
return bcrypt_1.default.hash(pwd, SALT_ROUNDS);
}
/**
* Useful for testing.
*/
function hashSync(pwd) {
return bcrypt_1.default.hashSync(pwd, SALT_ROUNDS);
}
/**
* See if a password passes the hash.
*/
function compare(pwd, hash) {
return bcrypt_1.default.compare(pwd, hash);
}
// **** Export Default **** //
exports.default = {
getHash,
hashSync,
compare,
};
//# sourceMappingURL=PwdUtil.js.map

1
lib/util/PwdUtil.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"PwdUtil.js","sourceRoot":"","sources":["../../src/util/PwdUtil.ts"],"names":[],"mappings":";;;;;AAAA,oDAA4B;AAG5B,yBAAyB;AAEzB,MAAM,WAAW,GAAG,EAAE,CAAC;AAGvB,yBAAyB;AAEzB;;GAEG;AACH,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,gBAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,gBAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,GAAW,EAAE,IAAY;IACxC,OAAO,gBAAM,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC;AAGD,8BAA8B;AAE9B,kBAAe;IACb,OAAO;IACP,QAAQ;IACR,OAAO;CACC,CAAC"}

74
lib/util/SessionUtil.js Normal file
View File

@@ -0,0 +1,74 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const HttpStatusCodes_1 = __importDefault(require("@src/constants/HttpStatusCodes"));
const classes_1 = require("@src/other/classes");
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const EnvVars_1 = __importDefault(require("../constants/EnvVars"));
// **** Variables **** //
// Errors
const Errors = {
ParamFalsey: 'Param is falsey',
Validation: 'JSON-web-token validation failed.',
};
// Options
const Options = {
expiresIn: EnvVars_1.default.Jwt.Exp,
};
// **** Functions **** //
/**
* Get session data from request object (i.e. ISessionUser)
*/
function getSessionData(req) {
const { Key } = EnvVars_1.default.CookieProps, jwt = req.signedCookies[Key];
return _decode(jwt);
}
/**
* Add a JWT to the response
*/
async function addSessionData(res, data) {
if (!res || !data) {
throw new classes_1.RouteError(HttpStatusCodes_1.default.BAD_REQUEST, Errors.ParamFalsey);
}
// Setup JWT
const jwt = await _sign(data), { Key, Options } = EnvVars_1.default.CookieProps;
// Return
return res.cookie(Key, jwt, Options);
}
/**
* Remove cookie
*/
function clearCookie(res) {
const { Key, Options } = EnvVars_1.default.CookieProps;
return res.clearCookie(Key, Options);
}
// **** Helper Functions **** //
/**
* Encrypt data and return jwt.
*/
function _sign(data) {
return new Promise((res, rej) => {
jsonwebtoken_1.default.sign(data, EnvVars_1.default.Jwt.Secret, { expiresIn: '1h' }, (err, token) => {
return err ? rej(err) : res(token || '');
});
});
}
/**
* Decrypt JWT and extract client data.
*/
function _decode(jwt) {
return new Promise((res, rej) => {
jsonwebtoken_1.default.verify(jwt, EnvVars_1.default.Jwt.Secret, undefined, (err, decoded) => {
return err ? rej(Errors.Validation) : res(decoded);
});
});
}
// **** Export default **** //
exports.default = {
addSessionData,
getSessionData,
clearCookie,
};
//# sourceMappingURL=SessionUtil.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SessionUtil.js","sourceRoot":"","sources":["../../src/util/SessionUtil.ts"],"names":[],"mappings":";;;;;AAEA,qFAA6D;AAC7D,gDAAgD;AAChD,gEAAwC;AAExC,mEAA2C;AAG3C,yBAAyB;AAEzB,SAAS;AACT,MAAM,MAAM,GAAG;IACb,WAAW,EAAE,iBAAiB;IAC9B,UAAU,EAAE,mCAAmC;CACvC,CAAC;AAEX,UAAU;AACV,MAAM,OAAO,GAAG;IACd,SAAS,EAAE,iBAAO,CAAC,GAAG,CAAC,GAAG;CAC3B,CAAC;AAGF,yBAAyB;AAEzB;;GAEG;AACH,SAAS,cAAc,CAAI,GAAY;IACrC,MAAM,EAAE,GAAG,EAAE,GAAG,iBAAO,CAAC,WAAW,EACjC,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAC3B,GAAa,EACb,IAAqB;IAErB,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,oBAAU,CAAC,yBAAe,CAAC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;IACxE,CAAC;IACD,YAAY;IACZ,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,EAC3B,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,iBAAO,CAAC,WAAW,CAAC;IACzC,SAAS;IACT,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,GAAa;IAChC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,iBAAO,CAAC,WAAW,CAAC;IAC7C,OAAO,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAGD,gCAAgC;AAEhC;;GAEG;AACH,SAAS,KAAK,CAAC,IAA8B;IAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9B,sBAAY,CAAC,IAAI,CACf,IAAI,EACJ,iBAAO,CAAC,GAAG,CAAC,MAAM,EAClB,EAAE,SAAS,EAAE,IAAI,EAAE,EACnB,CAAC,GAAiB,EAAE,KAAc,EAAE,EAAE;YACpC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAI,GAAW;IAC7B,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9B,sBAAY,CAAC,MAAM,CACjB,GAAG,EACH,iBAAO,CAAC,GAAG,CAAC,MAAM,EAClB,SAAS,EACT,CAAC,GAAiB,EAAE,OAA0C,EAAE,EAAE;YAChE,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAY,CAAC,CAAC;QAC1D,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAGD,8BAA8B;AAE9B,kBAAe;IACb,cAAc;IACd,cAAc;IACd,WAAW;CACH,CAAC"}

24
lib/util/misc.js Normal file
View File

@@ -0,0 +1,24 @@
"use strict";
/**
* Miscellaneous shared functions go here.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRandomInt = getRandomInt;
exports.tick = tick;
/**
* Get a random number between 1 and 1,000,000,000,000
*/
function getRandomInt() {
return Math.floor(Math.random() * 1000000000000);
}
/**
* Wait for a certain number of milliseconds.
*/
function tick(milliseconds) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, milliseconds);
});
}
//# sourceMappingURL=misc.js.map

1
lib/util/misc.js.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/util/misc.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAMH,oCAEC;AAKD,oBAMC;AAhBD;;GAEG;AACH,SAAgB,YAAY;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,aAAiB,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,SAAgB,IAAI,CAAC,YAAoB;IACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,UAAU,CAAC,GAAG,EAAE;YACd,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,YAAY,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC"}