Email Basics feature/118-emails #128
22
CHANGELOG.md
22
CHANGELOG.md
@ -2,8 +2,30 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||||
|
|
||||||
|
#### [v0.3.1](https://git.odit.services/lfk/backend/compare/v0.3.0...v0.3.1)
|
||||||
|
|
||||||
|
- Merge pull request 'Mail+Env documentation feature/123-mail_documentation' (#129) from feature/123-mail_documentation into dev [`61bbeb0`](https://git.odit.services/lfk/backend/commit/61bbeb0d8f3fd6bfafb65bd11eb4c076a27b4a53)
|
||||||
|
- Added get runners by team test [`69417e9`](https://git.odit.services/lfk/backend/commit/69417e93c081422561db1e211b12f32e539010ce)
|
||||||
|
- Table fix [`1f0c842`](https://git.odit.services/lfk/backend/commit/1f0c842d9e086456f1ae0f6908e474258a04beb4)
|
||||||
|
- Added documentation for the env vars [`13ccab5`](https://git.odit.services/lfk/backend/commit/13ccab5e289d0a629cefb7fe281a85a46058ae97)
|
||||||
|
- 🧾New changelog file version [CI SKIP] [skip ci] [`71898d5`](https://git.odit.services/lfk/backend/commit/71898d576c2620d2f2e2b4336e62f1d04a443201)
|
||||||
|
- 🧾New changelog file version [CI SKIP] [skip ci] [`2071c4d`](https://git.odit.services/lfk/backend/commit/2071c4db33bbb9fd41ef650b409cac789732225f)
|
||||||
|
- Merge pull request 'Alpha Release 0.3.1' (#127) from dev into main [`20f960e`](https://git.odit.services/lfk/backend/commit/20f960ed6700fe58c0556895e6485d26c4a4f5e2)
|
||||||
|
- Created the organizations/runners endpoint [`570c34b`](https://git.odit.services/lfk/backend/commit/570c34bed04e359f389a8f427486bf92891f1dcb)
|
||||||
|
- Created the runnerTeam/runners endpoint [`7be2971`](https://git.odit.services/lfk/backend/commit/7be2971a9e02bf0e784f7fe5cdd82afbbbf7f854)
|
||||||
|
- 🧾New changelog file version [CI SKIP] [skip ci] [`aedfcfc`](https://git.odit.services/lfk/backend/commit/aedfcfcc8359afd7dba4fa5e515e8e77fbb3fc6e)
|
||||||
|
- 🧾New changelog file version [CI SKIP] [skip ci] [`e6fe8fc`](https://git.odit.services/lfk/backend/commit/e6fe8fcd587751392970d3ee412559b4c1d60f21)
|
||||||
|
- Merge pull request 'new advanced endpoints feature/125-team_runner' (#126) from feature/125-team_runner into dev [`870fd47`](https://git.odit.services/lfk/backend/commit/870fd47c83389345d7b24a15df6a4e61e930d140)
|
||||||
|
- Changed order [`583a4bc`](https://git.odit.services/lfk/backend/commit/583a4bc0dd0de8026bb2eb6a9b0c31f59344e813)
|
||||||
|
- Added the basics about mail templates to the readme [`b5018eb`](https://git.odit.services/lfk/backend/commit/b5018eb11492884db9f4ec969c767c3cce53f105)
|
||||||
|
- Added get runners by org test [`f71a22f`](https://git.odit.services/lfk/backend/commit/f71a22f4dd9bf14d39ced91908f6f6a5d8395e56)
|
||||||
|
- Added a hint to ethereal.email [`53fcff7`](https://git.odit.services/lfk/backend/commit/53fcff77d00fc2b205ada0bcee7bdfe83d94a9f4)
|
||||||
|
- 🚀Bumped version to v0.3.1 [`db08760`](https://git.odit.services/lfk/backend/commit/db0876015bf0599dabb21357f172735888c79aa8)
|
||||||
|
|
||||||
#### [v0.3.0](https://git.odit.services/lfk/backend/compare/v0.2.1...v0.3.0)
|
#### [v0.3.0](https://git.odit.services/lfk/backend/compare/v0.2.1...v0.3.0)
|
||||||
|
|
||||||
|
> 24 January 2021
|
||||||
|
|
||||||
- Merge pull request 'Alpha Release 0.3.0' (#122) from dev into main [`c964591`](https://git.odit.services/lfk/backend/commit/c9645918398e62a80341d038b6b6b5c60ee4b1c7)
|
- Merge pull request 'Alpha Release 0.3.0' (#122) from dev into main [`c964591`](https://git.odit.services/lfk/backend/commit/c9645918398e62a80341d038b6b6b5c60ee4b1c7)
|
||||||
- Renamed files and classed from *Organisation* to *Organization*📝 [`c6c643e`](https://git.odit.services/lfk/backend/commit/c6c643ecf125f5fdf58b105f97efad32e8545dd4)
|
- Renamed files and classed from *Organisation* to *Organization*📝 [`c6c643e`](https://git.odit.services/lfk/backend/commit/c6c643ecf125f5fdf58b105f97efad32e8545dd4)
|
||||||
- Changed organisation* to organization* in descriptions, comments and endoints ✏ [`ef15d0d`](https://git.odit.services/lfk/backend/commit/ef15d0d57619d79e014e0c0331965ca2bc664254)
|
- Changed organisation* to organization* in descriptions, comments and endoints ✏ [`ef15d0d`](https://git.odit.services/lfk/backend/commit/ef15d0d57619d79e014e0c0331965ca2bc664254)
|
||||||
|
30
README.md
30
README.md
@ -35,11 +35,41 @@ yarn test:watch
|
|||||||
yarn test:ci
|
yarn test:ci
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Use your own mail templates
|
||||||
|
> You use your own mail templates by replacing the default ones we provided (either in-code or by mounting them into the /app/static/mail_templates folder).
|
||||||
|
|
||||||
|
The mail templates always come in a .html and a .txt variant to provide compatability with legacy mail clients.
|
||||||
|
Currently the following templates exist:
|
||||||
|
* pw-reset.(html/txt)
|
||||||
|
|
||||||
### Generate Docs
|
### Generate Docs
|
||||||
```bash
|
```bash
|
||||||
yarn docs
|
yarn docs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## ENV Vars
|
||||||
|
> You can provide them via .env file or docker env vars.
|
||||||
|
> You can use the `test:ci:generate_env` package script to generate a example env (uses [ethereal.email](https://ethereal.email) as the mailserver).
|
||||||
|
|
||||||
|
| Name | Type | Default | Description
|
||||||
|
| - | - | - | -
|
||||||
|
| APP_PORT | Number | 4010 | The port the backend server listens on. Is optional.
|
||||||
|
| DB_TYPE | String | N/A | The type of the db u want to use. It has to be supported by typeorm. Possible: `sqlite`, `mysql`, `postgresql`
|
||||||
|
| DB_HOST | String | N/A | The db's host's ip-address/fqdn or file path for sqlite
|
||||||
|
| DB_PORT | String | N/A | The db's port
|
||||||
|
| DB_USER | String | N/A | The user for accessing the db
|
||||||
|
| DB_PASSWORD | String | N/A | The user's password for accessing the db
|
||||||
|
| DB_NAME | String | N/A | The db's name
|
||||||
|
| NODE_ENV | String | dev | The apps env - influences debug info.
|
||||||
|
| POSTALCODE_COUNTRYCODE | String/CountryCode | N/A | The countrycode used to validate address's postal codes
|
||||||
|
| PHONE_COUNTRYCODE | String/CountryCode | null (international) | The countrycode used to validate phone numers
|
||||||
|
| SEED_TEST_DATA | Boolean | False | If you want the app to seed some example data set this to true
|
||||||
|
| MAIL_SERVER | String | N/A | The smtp server's ip-address/fqdn
|
||||||
|
| MAIL_PORT | String | N/A | The smtp server's port
|
||||||
|
| MAIL_USER | String | N/A | The username for sending mails
|
||||||
|
| MAIL_PASSWORD | String | N/A | The user's password for sending mails
|
||||||
|
| MAIL_FROM | String | N/A | The from-address for sending mails
|
||||||
|
|
||||||
## Recommended Editor
|
## Recommended Editor
|
||||||
|
|
||||||
[Visual Studio Code](https://code.visualstudio.com/)
|
[Visual Studio Code](https://code.visualstudio.com/)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/lfk-backend",
|
"name": "@odit/lfk-backend",
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"main": "src/app.ts",
|
"main": "src/app.ts",
|
||||||
"repository": "https://git.odit.services/lfk/backend",
|
"repository": "https://git.odit.services/lfk/backend",
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -4,8 +4,10 @@ import { getConnectionManager, Repository } from 'typeorm';
|
|||||||
import { RunnerOrganizationHasRunnersError, RunnerOrganizationHasTeamsError, RunnerOrganizationIdsNotMatchingError, RunnerOrganizationNotFoundError } from '../errors/RunnerOrganizationErrors';
|
import { RunnerOrganizationHasRunnersError, RunnerOrganizationHasTeamsError, RunnerOrganizationIdsNotMatchingError, RunnerOrganizationNotFoundError } from '../errors/RunnerOrganizationErrors';
|
||||||
import { CreateRunnerOrganization } from '../models/actions/create/CreateRunnerOrganization';
|
import { CreateRunnerOrganization } from '../models/actions/create/CreateRunnerOrganization';
|
||||||
import { UpdateRunnerOrganization } from '../models/actions/update/UpdateRunnerOrganization';
|
import { UpdateRunnerOrganization } from '../models/actions/update/UpdateRunnerOrganization';
|
||||||
|
import { Runner } from '../models/entities/Runner';
|
||||||
import { RunnerOrganization } from '../models/entities/RunnerOrganization';
|
import { RunnerOrganization } from '../models/entities/RunnerOrganization';
|
||||||
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
||||||
|
import { ResponseRunner } from '../models/responses/ResponseRunner';
|
||||||
import { ResponseRunnerOrganization } from '../models/responses/ResponseRunnerOrganization';
|
import { ResponseRunnerOrganization } from '../models/responses/ResponseRunnerOrganization';
|
||||||
import { RunnerController } from './RunnerController';
|
import { RunnerController } from './RunnerController';
|
||||||
import { RunnerTeamController } from './RunnerTeamController';
|
import { RunnerTeamController } from './RunnerTeamController';
|
||||||
@ -48,6 +50,22 @@ export class RunnerOrganizationController {
|
|||||||
return new ResponseRunnerOrganization(runnerOrg);
|
return new ResponseRunnerOrganization(runnerOrg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('/:id/runners')
|
||||||
|
@Authorized(["RUNNER:GET", "SCAN:GET"])
|
||||||
|
@ResponseSchema(ResponseRunner, { isArray: true })
|
||||||
|
@ResponseSchema(RunnerOrganizationNotFoundError, { statusCode: 404 })
|
||||||
|
@OpenAPI({ description: 'Lists all runners from this org and it\'s teams (if you don\'t provide the ?onlyDirect=true param). <br> This includes the runner\'s group and distance ran.' })
|
||||||
|
async getRunners(@Param('id') id: number, @QueryParam('onlyDirect') onlyDirect: boolean) {
|
||||||
|
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
|
||||||
|
let runners: Runner[];
|
||||||
|
if (!onlyDirect) { runners = (await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.scans', 'runners.scans.track', 'teams', 'teams.runners', 'teams.runners.group', 'teams.runners.scans', 'teams.runners.scans.track'] })).allRunners; }
|
||||||
|
else { runners = (await this.runnerOrganizationRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.scans', 'runners.scans.track'] })).runners; }
|
||||||
|
runners.forEach(runner => {
|
||||||
|
responseRunners.push(new ResponseRunner(runner));
|
||||||
|
});
|
||||||
|
return responseRunners;
|
||||||
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authorized("ORGANIZATION:CREATE")
|
@Authorized("ORGANIZATION:CREATE")
|
||||||
@ResponseSchema(ResponseRunnerOrganization)
|
@ResponseSchema(ResponseRunnerOrganization)
|
||||||
|
@ -6,6 +6,7 @@ import { CreateRunnerTeam } from '../models/actions/create/CreateRunnerTeam';
|
|||||||
import { UpdateRunnerTeam } from '../models/actions/update/UpdateRunnerTeam';
|
import { UpdateRunnerTeam } from '../models/actions/update/UpdateRunnerTeam';
|
||||||
import { RunnerTeam } from '../models/entities/RunnerTeam';
|
import { RunnerTeam } from '../models/entities/RunnerTeam';
|
||||||
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
||||||
|
import { ResponseRunner } from '../models/responses/ResponseRunner';
|
||||||
import { ResponseRunnerTeam } from '../models/responses/ResponseRunnerTeam';
|
import { ResponseRunnerTeam } from '../models/responses/ResponseRunnerTeam';
|
||||||
import { RunnerController } from './RunnerController';
|
import { RunnerController } from './RunnerController';
|
||||||
|
|
||||||
@ -47,6 +48,20 @@ export class RunnerTeamController {
|
|||||||
return new ResponseRunnerTeam(runnerTeam);
|
return new ResponseRunnerTeam(runnerTeam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('/:id/runners')
|
||||||
|
@Authorized(["RUNNER:GET", "SCAN:GET"])
|
||||||
|
@ResponseSchema(ResponseRunner, { isArray: true })
|
||||||
|
@ResponseSchema(RunnerTeamNotFoundError, { statusCode: 404 })
|
||||||
|
@OpenAPI({ description: 'Lists all runners from this team. <br> This includes the runner\'s group and distance ran.' })
|
||||||
|
async getRunners(@Param('id') id: number) {
|
||||||
|
let responseRunners: ResponseRunner[] = new Array<ResponseRunner>();
|
||||||
|
const runners = (await this.runnerTeamRepository.findOne({ id: id }, { relations: ['runners', 'runners.group', 'runners.scans', 'runners.scans.track'] })).runners;
|
||||||
|
runners.forEach(runner => {
|
||||||
|
responseRunners.push(new ResponseRunner(runner));
|
||||||
|
});
|
||||||
|
return responseRunners;
|
||||||
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@Authorized("TEAM:CREATE")
|
@Authorized("TEAM:CREATE")
|
||||||
@ResponseSchema(ResponseRunnerTeam)
|
@ResponseSchema(ResponseRunnerTeam)
|
||||||
|
@ -33,36 +33,106 @@ describe('GET /api/runners after adding', () => {
|
|||||||
let added_org_id;
|
let added_org_id;
|
||||||
let added_runner;
|
let added_runner;
|
||||||
it('creating a new org with just a name should return 200', async () => {
|
it('creating a new org with just a name should return 200', async () => {
|
||||||
const res1 = await axios.post(base + '/api/organizations', {
|
const res = await axios.post(base + '/api/organizations', {
|
||||||
"name": "test123"
|
"name": "test123"
|
||||||
}, axios_config);
|
}, axios_config);
|
||||||
let added_org = res1.data
|
let added_org = res.data
|
||||||
added_org_id = added_org.id;
|
added_org_id = added_org.id;
|
||||||
expect(res1.status).toEqual(200);
|
expect(res.status).toEqual(200);
|
||||||
expect(res1.headers['content-type']).toContain("application/json")
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
});
|
});
|
||||||
it('creating a new runner with only needed params should return 200', async () => {
|
it('creating a new runner with only needed params should return 200', async () => {
|
||||||
const res2 = await axios.post(base + '/api/runners', {
|
const res = await axios.post(base + '/api/runners', {
|
||||||
"firstname": "first",
|
"firstname": "first",
|
||||||
"lastname": "last",
|
"lastname": "last",
|
||||||
"group": added_org_id
|
"group": added_org_id
|
||||||
}, axios_config);
|
}, axios_config);
|
||||||
added_runner = res2.data;
|
added_runner = res.data;
|
||||||
expect(res2.status).toEqual(200);
|
expect(res.status).toEqual(200);
|
||||||
expect(res2.headers['content-type']).toContain("application/json")
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
});
|
});
|
||||||
it('explicit get should return 200', async () => {
|
it('explicit get should return 200', async () => {
|
||||||
const res3 = await axios.get(base + '/api/runners/' + added_runner.id, axios_config);
|
const res = await axios.get(base + '/api/runners/' + added_runner.id, axios_config);
|
||||||
expect(res3.status).toEqual(200);
|
expect(res.status).toEqual(200);
|
||||||
expect(res3.headers['content-type']).toContain("application/json")
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
let gotten_runner = res3.data
|
let gotten_runner = res.data
|
||||||
expect(gotten_runner).toEqual(added_runner);
|
expect(gotten_runner).toEqual(added_runner);
|
||||||
});
|
});
|
||||||
it('get from all runners should return 200', async () => {
|
it('get from all runners should return 200', async () => {
|
||||||
const res4 = await axios.get(base + '/api/runners/', axios_config);
|
const res = await axios.get(base + '/api/runners/', axios_config);
|
||||||
expect(res4.status).toEqual(200);
|
expect(res.status).toEqual(200);
|
||||||
expect(res4.headers['content-type']).toContain("application/json")
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
let gotten_runners = res4.data
|
let gotten_runners = res.data
|
||||||
expect(gotten_runners).toContainEqual(added_runner);
|
expect(gotten_runners).toContainEqual(added_runner);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// ---------------
|
||||||
|
describe('GET /api/organizations/:id/runners after adding', () => {
|
||||||
|
let added_org_id;
|
||||||
|
let added_runner;
|
||||||
|
it('creating a new org with just a name should return 200', async () => {
|
||||||
|
const res = await axios.post(base + '/api/organizations', {
|
||||||
|
"name": "test123"
|
||||||
|
}, axios_config);
|
||||||
|
let added_org = res.data
|
||||||
|
added_org_id = added_org.id;
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
|
});
|
||||||
|
it('creating a new runner with only needed params should return 200', async () => {
|
||||||
|
const res = await axios.post(base + '/api/runners', {
|
||||||
|
"firstname": "first",
|
||||||
|
"lastname": "last",
|
||||||
|
"group": added_org_id
|
||||||
|
}, axios_config);
|
||||||
|
added_runner = res.data;
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
|
});
|
||||||
|
it('check if scans was added via the orgs/runners endpoint.', async () => {
|
||||||
|
const res = await axios.get(base + '/api/organizations/' + added_org_id + "/runners", axios_config);
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.headers['content-type']).toContain("application/json");
|
||||||
|
expect(res.data).toContainEqual(added_runner);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// ---------------
|
||||||
|
describe('GET /api/teams/:id/runners after adding', () => {
|
||||||
|
let added_org_id;
|
||||||
|
let added_team;
|
||||||
|
let added_runner;
|
||||||
|
it('creating a new org with just a name should return 200', async () => {
|
||||||
|
const res = await axios.post(base + '/api/organizations', {
|
||||||
|
"name": "test123"
|
||||||
|
}, axios_config);
|
||||||
|
let added_org = res.data
|
||||||
|
added_org_id = added_org.id;
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
|
});
|
||||||
|
it('creating a new team with a parent org should return 200', async () => {
|
||||||
|
const res = await axios.post(base + '/api/teams', {
|
||||||
|
"name": "test_team",
|
||||||
|
"parentGroup": added_org_id
|
||||||
|
}, axios_config);
|
||||||
|
added_team = res.data;
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
|
});
|
||||||
|
it('creating a new runner with only needed params should return 200', async () => {
|
||||||
|
const res = await axios.post(base + '/api/runners', {
|
||||||
|
"firstname": "first",
|
||||||
|
"lastname": "last",
|
||||||
|
"group": added_team.id
|
||||||
|
}, axios_config);
|
||||||
|
added_runner = res.data;
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.headers['content-type']).toContain("application/json")
|
||||||
|
});
|
||||||
|
it('check if scans was added via the orgs/runners endpoint.', async () => {
|
||||||
|
const res = await axios.get(base + '/api/teams/' + added_team.id + "/runners", axios_config);
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(res.headers['content-type']).toContain("application/json");
|
||||||
|
expect(res.data).toContainEqual(added_runner);
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user