Bovsi Studios Timeclock app
6 |This app will help Bovsi Studios keep track of work-things
7 |8 | Signup with 9 | email 10 | Login with 11 | Username 12 |
13 |Web.Api.Infrastructure>**dotnet ef database update --context AppDbContext**
12 | - Web.Api.Infrastructure>**dotnet ef database update --context AppIdentityDbContext**
13 |
14 | # Visual Studio
15 | Open the solution file AspNetCoreApiStarter.sln
and build/run.
16 |
17 | # Visual Studio Code
18 | Open the src
folder and F5
to build/run.
19 |
20 | # Swagger Enabled
21 | To explore and test the available APIs simply run the project and use the Swagger UI.
22 |
23 | The available APIs include:
24 | - POST `/api/accounts` - Creates a new user.
25 | - POST `/api/auth/login` - Authenticates a user.
26 | - POST `/api/auth/refreshtoken` - Refreshes expired access tokens.
27 | - GET `/api/protected` - Protected controller for testing role-based authorization.
28 |
29 | # Contact
30 | mark@fullstackmark.com
31 |
32 |
--------------------------------------------------------------------------------
/src/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to find out which attributes exist for C# debugging
3 | // Use hover for the description of the existing attributes
4 | // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": ".NET Core Launch (web)",
9 | "type": "coreclr",
10 | "request": "launch",
11 | "preLaunchTask": "build",
12 | // If you have changed target frameworks, make sure to update the program path.
13 | "program": "${workspaceFolder}/Web.Api/bin/Debug/netcoreapp2.1/Web.Api.dll",
14 | "args": [],
15 | "cwd": "${workspaceFolder}/Web.Api",
16 | "stopAtEntry": false,
17 | "internalConsoleOptions": "openOnSessionStart",
18 | "launchBrowser": {
19 | "enabled": true,
20 | "args": "https://localhost:5002/swagger",
21 | "windows": {
22 | "command": "cmd.exe",
23 | "args": "/C start https://localhost:5002/swagger"
24 | },
25 | "osx": {
26 | "command": "open"
27 | },
28 | "linux": {
29 | "command": "xdg-open"
30 | }
31 | },
32 | "env": {
33 | "ASPNETCORE_ENVIRONMENT": "Development"
34 | },
35 | "sourceFileMap": {
36 | "/Views": "${workspaceFolder}/Views"
37 | }
38 | },
39 | {
40 | "name": ".NET Core Attach",
41 | "type": "coreclr",
42 | "request": "attach",
43 | "processId": "${command:pickProcess}"
44 | }
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/src/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "build",
6 | "command": "dotnet",
7 | "type": "process",
8 | "args": [
9 | "build",
10 | "${workspaceFolder}/Web.Api/Web.Api.csproj"
11 | ],
12 | "problemMatcher": "$msCompile"
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/src/Tests/Web.Api.Core.UnitTests/Domain/Entities/UserUnitTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Web.Api.Core.Domain.Entities;
3 | using Xunit;
4 |
5 | namespace Web.Api.Core.UnitTests.Domain.Entities
6 | {
7 | public class UserUnitTests
8 | {
9 | [Fact]
10 | public void HasValidRefreshToken_GivenValidToken_ShouldReturnTrue()
11 | {
12 | // arrange
13 | const string refreshToken = "1234";
14 | var user = new User("", "", "", "");
15 | user.AddRereshToken(refreshToken, Guid.NewGuid(), "127.0.0.1");
16 |
17 | // act
18 | var result = user.HasValidRefreshToken(refreshToken);
19 |
20 | Assert.True(result);
21 | }
22 |
23 | [Fact]
24 | public void HasValidRefreshToken_GivenExpiredToken_ShouldReturnFalse()
25 | {
26 | // arrange
27 | const string refreshToken = "1234";
28 | var user = new User("", "", "", "");
29 | user.AddRereshToken(refreshToken, Guid.NewGuid(), "127.0.0.1", -6); // Provision with token 6 days old
30 |
31 | // act
32 | var result = user.HasValidRefreshToken(refreshToken);
33 |
34 | Assert.False(result);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Tests/Web.Api.Core.UnitTests/UseCases/RegisterUserUseCaseUnitTests.cs:
--------------------------------------------------------------------------------
1 | using Moq;
2 | using Web.Api.Core.Dto.GatewayResponses.Repositories;
3 | using Web.Api.Core.Dto.UseCaseRequests;
4 | using Web.Api.Core.Dto.UseCaseResponses;
5 | using Web.Api.Core.Interfaces;
6 | using Web.Api.Core.Interfaces.Gateways.Repositories;
7 | using Web.Api.Core.UseCases;
8 | using Xunit;
9 |
10 | namespace Web.Api.Core.UnitTests.UseCases
11 | {
12 | public class RegisterUserUseCaseUnitTests
13 | {
14 | [Fact]
15 | public async void Handle_GivenValidRegistrationDetails_ShouldSucceed()
16 | {
17 | // arrange
18 |
19 | // 1. We need to store the user data somehow
20 | var mockUserRepository = new MockThis app will help Bovsi Studios keep track of work-things
7 |8 | Signup with 9 | email 10 | Login with 11 | Username 12 |
13 |2 | settings works! 3 |
-------------------------------------------------------------------------------- /src/WebServer/AngularApp/src/app/features/dashboard/accountHome/accountHome.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maylordev/AspNetCore2Angular7/6b74d14d2e048385272d02cb1361e8e131cc0c13/src/WebServer/AngularApp/src/app/features/dashboard/accountHome/accountHome.component.scss -------------------------------------------------------------------------------- /src/WebServer/AngularApp/src/app/features/dashboard/accountHome/accountHome.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-account-home', 5 | templateUrl: './accountHome.component.html', 6 | styleUrls: ['./accountHome.component.scss'] 7 | }) 8 | export class AccountHomeComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/WebServer/AngularApp/src/app/features/dashboard/dashboard.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {FormsModule} from '@angular/forms'; 4 | 5 | import {DashboardRoutingModule} from './dashboard.routing'; 6 | import {RootComponent} from './root/root.component'; 7 | import {HomeComponent} from './home/home.component'; 8 | 9 | import {SharedModule} from '../../shared/shared.module'; 10 | import {AuthGuard} from '../../auth.guard'; 11 | import {AccountHomeComponent} from './accountHome/accountHome.component'; 12 | 13 | @NgModule({ 14 | imports: [CommonModule, FormsModule, DashboardRoutingModule, SharedModule], 15 | declarations: [RootComponent, HomeComponent, AccountHomeComponent], 16 | exports: [], 17 | providers: [AuthGuard] 18 | }) 19 | export class DashboardModule {} 20 | -------------------------------------------------------------------------------- /src/WebServer/AngularApp/src/app/features/dashboard/dashboard.routing.ts: -------------------------------------------------------------------------------- 1 | import {ModuleWithProviders, NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | 4 | import {RootComponent} from './root/root.component'; 5 | import {HomeComponent} from './home/home.component'; 6 | import {AuthGuard} from '../../auth.guard'; 7 | import {AccountHomeComponent} from './accountHome/accountHome.component'; 8 | 9 | const dashboardRoutes: Routes = [ 10 | { 11 | path: 'dashboard', 12 | component: RootComponent, 13 | canActivate: [AuthGuard], 14 | 15 | children: [ 16 | {path: '', component: HomeComponent}, 17 | {path: 'home', component: HomeComponent}, 18 | {path: 'account', component: AccountHomeComponent} 19 | ] 20 | } 21 | ]; 22 | @NgModule({ 23 | imports: [RouterModule.forChild(dashboardRoutes)], 24 | exports: [RouterModule] 25 | }) 26 | export class DashboardRoutingModule {} 27 | -------------------------------------------------------------------------------- /src/WebServer/AngularApp/src/app/features/dashboard/home/home.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maylordev/AspNetCore2Angular7/6b74d14d2e048385272d02cb1361e8e131cc0c13/src/WebServer/AngularApp/src/app/features/dashboard/home/home.component.css -------------------------------------------------------------------------------- /src/WebServer/AngularApp/src/app/features/dashboard/home/home.component.html: -------------------------------------------------------------------------------- 1 |2 | home works! 3 |
4 | -------------------------------------------------------------------------------- /src/WebServer/AngularApp/src/app/features/dashboard/home/home.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HomeComponent } from './home.component'; 4 | 5 | describe('HomeComponent', () => { 6 | let component: HomeComponent; 7 | let fixture: ComponentFixture
13 | Request ID: @Model.RequestId
14 |
19 | Swapping to Development environment will display more detailed information about the error that occurred. 20 |
21 |22 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 23 |
24 | -------------------------------------------------------------------------------- /src/WebServer/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using Microsoft.AspNetCore.Mvc.RazorPages; 8 | 9 | namespace WebServer.Pages 10 | { 11 | public class ErrorModel : PageModel 12 | { 13 | public string RequestId { get; set; } 14 | 15 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 16 | 17 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 18 | public void OnGet() 19 | { 20 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/WebServer/Pages/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using WebServer 2 | @namespace WebServer.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /src/WebServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | // ! Used only as an example template. 3 | // ! Never store any ACTUAL settings in here. 4 | // ! This file will be checked into source control 5 | // ! and be used by developers to setup their own appsettings.{env.EnvrionmentName}.json file 6 | "Logging": { 7 | "LogLevel": { 8 | "Default": "Debug", 9 | "System": "Information", 10 | "Microsoft": "Information" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WebServer/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "@angular/material-moment-adapter": { 6 | "version": "7.0.2", 7 | "resolved": "https://registry.npmjs.org/@angular/material-moment-adapter/-/material-moment-adapter-7.0.2.tgz", 8 | "integrity": "sha512-vMlaa06apA10s2umyTupudfTudUHx3oJGv9nUsN5mgE8m548oTah3d15G5QGVj8z1wXagniRdIQR+4e8IoWnTQ==", 9 | "requires": { 10 | "tslib": "^1.7.1" 11 | } 12 | }, 13 | "tslib": { 14 | "version": "1.9.3", 15 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", 16 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/WebServer/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maylordev/AspNetCore2Angular7/6b74d14d2e048385272d02cb1361e8e131cc0c13/src/WebServer/wwwroot/favicon.ico --------------------------------------------------------------------------------