Skip to content

Commit

Permalink
Merge pull request #150 from alirizaadiyahsi/dev
Browse files Browse the repository at this point in the history
Upgraded .net core to v3.0
  • Loading branch information
alirizaadiyahsi authored Sep 24, 2019
2 parents fd6cfa5 + 5824961 commit 440ac02
Show file tree
Hide file tree
Showing 214 changed files with 1,277 additions and 127 deletions.
31 changes: 6 additions & 25 deletions Nucleus.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nucleus.Tests.Application",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nucleus.Tests.Web.Api", "test\Nucleus.Tests.Web.Api\Nucleus.Tests.Web.Api.csproj", "{02306886-8DC2-4E72-BF50-CA2EF5626794}"
EndProject
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "nucleus-web-vue", "src\nucleus-web-vue\", "{35E30CCF-CC26-4E84-AA31-325042BCBF21}"
ProjectSection(WebsiteProperties) = preProject
TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
Debug.AspNetCompiler.VirtualPath = "/localhost_49375"
Debug.AspNetCompiler.PhysicalPath = "src\nucleus-web-vue\"
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_49375\"
Debug.AspNetCompiler.Updateable = "true"
Debug.AspNetCompiler.ForceOverwrite = "true"
Debug.AspNetCompiler.FixedNames = "false"
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.VirtualPath = "/localhost_49375"
Release.AspNetCompiler.PhysicalPath = "src\nucleus-web-vue\"
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_49375\"
Release.AspNetCompiler.Updateable = "true"
Release.AspNetCompiler.ForceOverwrite = "true"
Release.AspNetCompiler.FixedNames = "false"
Release.AspNetCompiler.Debug = "False"
VWDPort = "49375"
SlnRelativePath = "src\nucleus-web-vue\"
EndProjectSection
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nucleus.Web.Vue", "src\Nucleus.Web.Vue\Nucleus.Web.Vue.csproj", "{13C2090F-16B5-49DB-86B8-E320FD977FD2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -88,10 +69,10 @@ Global
{02306886-8DC2-4E72-BF50-CA2EF5626794}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02306886-8DC2-4E72-BF50-CA2EF5626794}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02306886-8DC2-4E72-BF50-CA2EF5626794}.Release|Any CPU.Build.0 = Release|Any CPU
{35E30CCF-CC26-4E84-AA31-325042BCBF21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35E30CCF-CC26-4E84-AA31-325042BCBF21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35E30CCF-CC26-4E84-AA31-325042BCBF21}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{35E30CCF-CC26-4E84-AA31-325042BCBF21}.Release|Any CPU.Build.0 = Debug|Any CPU
{13C2090F-16B5-49DB-86B8-E320FD977FD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{13C2090F-16B5-49DB-86B8-E320FD977FD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13C2090F-16B5-49DB-86B8-E320FD977FD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13C2090F-16B5-49DB-86B8-E320FD977FD2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -106,7 +87,7 @@ Global
{114AFE01-0628-451E-AD9A-5FFEA231022B} = {B7A0D987-5893-493C-A60A-8F1818D931E0}
{B842DDCA-1842-49FF-BE41-658AF772ED18} = {B7A0D987-5893-493C-A60A-8F1818D931E0}
{02306886-8DC2-4E72-BF50-CA2EF5626794} = {B7A0D987-5893-493C-A60A-8F1818D931E0}
{35E30CCF-CC26-4E84-AA31-325042BCBF21} = {C243FF0E-FA80-4C4C-8B5E-AD681D54E07A}
{13C2090F-16B5-49DB-86B8-E320FD977FD2} = {C243FF0E-FA80-4C4C-8B5E-AD681D54E07A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F0972965-9C8E-4058-BC88-3DFF23CFA05A}
Expand Down
71 changes: 36 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

# Nucleus

Web API startup template with a Vue Client demo.
Web API startup template with a Vue Client application.

<br/>
<br/>

## How to Start?

**NOTE:** Requires Visual Studio 2019 v16.3 or later **for Windows** and Visual Studio 2019 for Mac v8.3 or later **for macOS**.

- Select `Nucleus.Web.Api` project "**Set as Startup Project**"
- Open "**Package Manager Console**" and select default project as `src/Nucleus.EntityFramework`
- Run `update-database` command to create database.
Expand All @@ -27,10 +29,6 @@ Web API startup template with a Vue Client demo.

<img src="_images/_register.png" alt="Vue Client Demo" class="img-thumbnail" />

### Dashboard

<img src="_images/_dashboard.png" alt="Vue Client Demo" class="img-thumbnail" />

### List Pages

<img src="_images/_users.png" alt="Vue Client Demo" class="img-thumbnail" />
Expand All @@ -53,53 +51,57 @@ Web API startup template with a Vue Client demo.

## Adding New Language

- Add json file to store language keys and values to `Nucleus\src\Nucleus.Web.Vue\src\assets\js\locales\tr.json`
- Add json file to store language keys and values to `Nucleus\src\Nucleus.Web.Vue\src\assets\localizations\your_language.json`
- Copy `en.json` content and translate the values to target language.
- Add country flag to `Nucleus.Web.Vue\src\assets\images\icons\flags\tr.png`. Get images from http://www.iconarchive.com/show/flag-icons-by-gosquared.html
- Add country flag to `Nucleus.Web.Vue\src\assets\images\icons\flags\your_country.png`. Get images from http://www.iconarchive.com/show/flag-icons-by-gosquared.html
- Add language to language selection menu in `Nucleus\src\Nucleus.Web.Vue\src\account\account-layout.vue` and `Nucleus\src\Nucleus.Web.Vue\src\admin\components\menu\top-menu\top-menu.vue` like following

**account-layout.vue**

````html
<v-layout align-center justify-center row fill-height>
<v-menu class="mt-3">
<v-btn slot="activator" color="primary" dark outline round>
<v-menu>
<template v-slot:activator="{ on }">
<v-btn color="primary" dark outlined rounded v-on="on">
<img :src="require('@/assets/images/icons/flags/' + selectedLanguage.languageCode + '.png')" class="mr-2 ml-1" />
{{selectedLanguage.languageName}}
<v-icon dark class="ml-3">arrow_drop_down</v-icon>
<v-icon dark class="ml-3">mdi-menu-down</v-icon>
</v-btn>
<v-list>
<v-list-tile @click="changeLanguage('en', 'English')">
<img src="@/assets/images/icons/flags/en.png" class="mr-2" />
<v-list-tile-title>English</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="changeLanguage('tr', 'Türkçe')">
<img src="@/assets/images/icons/flags/tr.png" class="mr-2" />
<v-list-tile-title>Türkçe</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</v-layout>
</template>

<v-list>
<v-list-item @click="changeLanguage('en', 'English')">
<img src="@/assets/images/icons/flags/en.png" class="mr-2" />
<v-list-item-title>English</v-list-item-title>
</v-list-item>
<v-list-item @click="changeLanguage('tr', 'Türkçe')">
<img src="@/assets/images/icons/flags/tr.png" class="mr-2" />
<v-list-item-title>Türkçe</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
````

**top-menu.vue**

````html
<v-menu>
<v-btn slot="activator" color="primary">
<img :src="require('@/assets/images/icons/flags/' + selectedLanguage.languageCode + '.png')" class="mr-2" />
{{selectedLanguage.languageName}}
<v-icon dark class="ml-3">arrow_drop_down</v-icon>
</v-btn>
<template v-slot:activator="{ on }">
<v-btn color="primary" v-on="on">
<img :src="require('@/assets/images/icons/flags/' + selectedLanguage.languageCode + '.png')" class="mr-2 ml-1" />
{{selectedLanguage.languageName}}
<v-icon dark class="ml-3">mdi-menu-down</v-icon>
</v-btn>
</template>

<v-list>
<v-list-tile @click="changeLanguage('en', 'English')">
<v-list-item @click="changeLanguage('en', 'English')">
<img src="@/assets/images/icons/flags/en.png" class="mr-2" />
<v-list-tile-title>English</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="changeLanguage('tr', 'Türkçe')">
<v-list-item-title>English</v-list-item-title>
</v-list-item>
<v-list-item @click="changeLanguage('tr', 'Türkçe')">
<img src="@/assets/images/icons/flags/tr.png" class="mr-2" />
<v-list-tile-title>Türkçe</v-list-tile-title>
</v-list-tile>
<v-list-item-title>Türkçe</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
````
Expand All @@ -118,7 +120,6 @@ Web API startup template with a Vue Client demo.
- [ASP.NET Core Test Host](https://www.nuget.org/packages/Microsoft.AspNetCore.TestHost)
- [Authorization & Authentication](https://docs.microsoft.com/en-us/aspnet/core/security/?view=aspnetcore-2.1)
- [Exception Handling & Logging](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-2.1)
- [Microsoft.CodeCoverage](https://docs.microsoft.com/en-us/visualstudio/test/using-code-coverage-to-determine-how-much-code-is-being-tested?view=vs-2017)
- [Vue.js](https://vuejs.org/)
- [Vue Router](https://router.vuejs.org/)
- [Vuetify](https://vuetifyjs.com/en/)
Expand Down
7 changes: 7 additions & 0 deletions src/Nucleus.Application/Dto/Account/ForgotPasswordOutput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Nucleus.Application.Dto.Account
{
public class ForgotPasswordOutput
{
public string ResetToken { get; set; }
}
}
7 changes: 4 additions & 3 deletions src/Nucleus.Application/Nucleus.Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="8.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="6.1.1" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.18" />
<PackageReference Include="AutoMapper" Version="9.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.19" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Nucleus.Core/Nucleus.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0-preview7.19365.7" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions src/Nucleus.Core/Permissions/DefaultPermissions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public static List<Permission> All()
RoleCreate,
RoleUpdate,
RoleDelete

// add your permission to list
};
}

Expand Down Expand Up @@ -92,6 +94,8 @@ public static List<Permission> All()
Id = new Guid("8F76DE0B-114A-4DF8-A93D-CEC927D06A3C")
};

// add your permissions

// these strings are using on authorize attributes
public const string PermissionNameForAdministration = "Permissions_Administration";
public const string PermissionNameForMemberAccess = "Permissions_Member_Access";
Expand All @@ -103,5 +107,7 @@ public static List<Permission> All()
public const string PermissionNameForRoleCreate = "Permissions_Role_Create";
public const string PermissionNameForRoleUpdate = "Permissions_Role_Update";
public const string PermissionNameForRoleDelete = "Permissions_Role_Delete";

// add your permission names
}
}
8 changes: 4 additions & 4 deletions src/Nucleus.EntityFramework/Nucleus.EntityFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0-preview7.19365.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0-preview7.19362.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.0.0-preview7.19362.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0-preview7.19362.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web;
Expand All @@ -25,7 +24,7 @@ public static string ToQueryString(this object obj)
where p.GetValue(obj, null) != null
select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(obj, null).ToString());

return String.Join("&", properties.ToArray());
return string.Join("&", properties.ToArray());
}
}
}
2 changes: 1 addition & 1 deletion src/Nucleus.Utilities/Nucleus.Utilities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0-preview7.19362.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>

Expand Down
32 changes: 23 additions & 9 deletions src/Nucleus.Web.Api/Controller/Account/AccountController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Nucleus.Application.Dto;
using Nucleus.Application.Dto.Account;
Expand All @@ -26,16 +27,20 @@ public class AccountController : BaseController
private readonly JwtTokenConfiguration _jwtTokenConfiguration;
private readonly IConfiguration _configuration;
private readonly SmtpClient _smtpClient;
readonly ILogger<AccountController> _logger;


public AccountController(
UserManager<User> userManager,
IOptions<JwtTokenConfiguration> jwtTokenConfiguration,
IConfiguration configuration,
SmtpClient smtpClient)
IConfiguration configuration,
SmtpClient smtpClient,
ILogger<AccountController> logger)
{
_userManager = userManager;
_configuration = configuration;
_smtpClient = smtpClient;
_logger = logger;
_jwtTokenConfiguration = jwtTokenConfiguration.Value;
}

Expand Down Expand Up @@ -116,12 +121,12 @@ public async Task<ActionResult> ChangePassword([FromBody] ChangePasswordInput in
}

[HttpPost("/api/[action]")]
public async Task<ActionResult> ForgotPassword([FromBody] ForgotPasswordInput input)
public async Task<ActionResult<ForgotPasswordOutput>> ForgotPassword([FromBody] ForgotPasswordInput input)
{
var user = await FindUserByUserNameOrEmail(input.UserNameOrEmail);
if (user == null)
{
return BadRequest(new List<NameValueDto>
return NotFound(new List<NameValueDto>
{
new NameValueDto("UserNotFound", "User is not found!")
});
Expand All @@ -136,9 +141,17 @@ public async Task<ActionResult> ForgotPassword([FromBody] ForgotPasswordInput in
body: $"Please confirm your account by clicking this link: <a href='{callbackUrl}'>link</a>"
);
message.IsBodyHtml = true;
await _smtpClient.SendMailAsync(message);

return Ok();
#if !DEBUG
await _smtpClient.SendMailAsync(message);
#endif
_logger.LogInformation(Environment.NewLine + Environment.NewLine +
"******************* Reset Password Link *******************" +
Environment.NewLine + Environment.NewLine +
callbackUrl +
Environment.NewLine + Environment.NewLine +
"***********************************************************" +
Environment.NewLine);
return Ok(new ForgotPasswordOutput { ResetToken = resetToken });
}

[HttpPost("/api/[action]")]
Expand All @@ -147,7 +160,7 @@ public async Task<ActionResult> ResetPassword([FromBody] ResetPasswordInput inpu
var user = await FindUserByUserNameOrEmail(input.UserNameOrEmail);
if (user == null)
{
return BadRequest(new List<NameValueDto>
return NotFound(new List<NameValueDto>
{
new NameValueDto("UserNotFound", "User is not found!")
});
Expand Down Expand Up @@ -181,7 +194,8 @@ private async Task<ClaimsIdentity> CreateClaimsIdentityAsync(string userNameOrEm
return new ClaimsIdentity(new GenericIdentity(userNameOrEmail, "Token"), new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userNameOrEmail),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, userToVerify.Id.ToString())
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/Nucleus.Web.Api/Controller/Roles/RolesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public async Task<ActionResult> PostRoles([FromBody]CreateOrUpdateRoleInput inpu

if (identityResult.Succeeded)
{
return Ok();
return Created(Url.Action("PostRoles"), identityResult);
}

return BadRequest(identityResult.Errors.Select(e => new NameValueDto(e.Code, e.Description)));
Expand Down Expand Up @@ -74,7 +74,7 @@ public async Task<ActionResult> DeleteRoles(Guid id)

if (identityResult.Succeeded)
{
return Ok();
return NoContent();
}

return BadRequest(identityResult.Errors.Select(e => new NameValueDto(e.Code, e.Description)));
Expand Down
2 changes: 1 addition & 1 deletion src/Nucleus.Web.Api/Controller/Users/UsersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public async Task<ActionResult> PostUsers([FromBody]CreateOrUpdateUserInput inpu

if (identityResult.Succeeded)
{
return Ok();
return Created(Url.Action("PostUsers"), identityResult);
}

return BadRequest(identityResult.Errors.Select(e => new NameValueDto(e.Code, e.Description)));
Expand Down
Loading

0 comments on commit 440ac02

Please sign in to comment.