boilercraft 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/bin/boilercraft.js +110 -0
- package/cli/app.js +596 -0
- package/cli/ui.js +356 -0
- package/docs/STACK_ENGINE.md +93 -0
- package/docs/assets/cli-create.svg +52 -0
- package/docs/assets/cli-menu.svg +47 -0
- package/docs/stacks/dotnet-core.md +69 -0
- package/docs/stacks/laravel-vue.md +46 -0
- package/docs/stacks/nextjs.md +58 -0
- package/docs/stacks/node-express.md +58 -0
- package/docs/stacks/raw-php.md +130 -0
- package/main.js +82 -0
- package/package.json +86 -0
- package/public/index.html +721 -0
- package/public/logo.png +17 -0
- package/public/logo.svg +17 -0
- package/server.js +84 -0
- package/services/componentGenerator.js +195 -0
- package/services/engine/scaffoldEngine.js +517 -0
- package/services/engine/toolInstaller.js +232 -0
- package/services/engine/versionCatalog.js +115 -0
- package/services/generate.js +46 -0
- package/services/projectGenerator.js +686 -0
- package/services/readmeGenerator.js +221 -0
- package/services/themeGenerator.js +150 -0
- package/services/versionResolver.js +176 -0
- package/stacks/dotnet-core/overlays/api/Controllers/ProductsController.cs +33 -0
- package/stacks/dotnet-core/overlays/api/Program.cs +33 -0
- package/stacks/dotnet-core/overlays/api/wwwroot/index.html +38 -0
- package/stacks/dotnet-core/overlays/api-auth/Controllers/AuthController.cs +87 -0
- package/stacks/dotnet-core/overlays/common/Data/ApplicationDbContext.cs +25 -0
- package/stacks/dotnet-core/overlays/common/Models/Product.cs +19 -0
- package/stacks/dotnet-core/overlays/mvc/Controllers/ProductsController.cs +84 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Home/Index.cshtml +23 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Create.cshtml +16 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Delete.cshtml +16 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Edit.cshtml +17 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Index.cshtml +46 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/_Form.cshtml +19 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Controllers/AccountController.cs +98 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Models/AppUser.cs +48 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Login.cshtml +35 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Register.cshtml +41 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Shared/_AuthNav.cshtml +22 -0
- package/stacks/dotnet-core/snippets/packages-auth.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-common.xml +5 -0
- package/stacks/dotnet-core/snippets/packages-ef.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-mssql.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-mysql.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-swagger.xml +4 -0
- package/stacks/dotnet-core/stack.json +426 -0
- package/stacks/laravel/overlays/auth/app/Http/Controllers/Api/AuthController.php +67 -0
- package/stacks/laravel/overlays/common/app/Http/Controllers/BoilerCraftController.php +14 -0
- package/stacks/laravel/overlays/common/resources/views/boilercraft.blade.php +36 -0
- package/stacks/laravel/overlays/inertia-common/resources/views/app.blade.php +15 -0
- package/stacks/laravel/overlays/inertia-react/resources/js/Pages/Welcome.jsx +18 -0
- package/stacks/laravel/overlays/inertia-react/resources/js/app.jsx +13 -0
- package/stacks/laravel/overlays/inertia-vue/resources/js/Pages/Welcome.vue +23 -0
- package/stacks/laravel/overlays/inertia-vue/resources/js/app.js +13 -0
- package/stacks/laravel/snippets/api-routes.php +9 -0
- package/stacks/laravel/snippets/web-routes-inertia.php +7 -0
- package/stacks/laravel/snippets/web-routes.php +4 -0
- package/stacks/laravel/stack.json +477 -0
- package/stacks/nextjs/overlays/auth/src/lib/auth.js +36 -0
- package/stacks/nextjs/overlays/auth-app/src/app/api/auth/login/route.js +11 -0
- package/stacks/nextjs/overlays/auth-app/src/app/api/auth/register/route.js +14 -0
- package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/login.js +14 -0
- package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/register.js +17 -0
- package/stacks/nextjs/overlays/common/.env.example +3 -0
- package/stacks/nextjs/overlays/common/.env.local +3 -0
- package/stacks/nextjs/overlays/db/mongodb/src/lib/db.js +12 -0
- package/stacks/nextjs/overlays/db/mssql/src/lib/db.js +17 -0
- package/stacks/nextjs/overlays/db/mysql/src/lib/db.js +13 -0
- package/stacks/nextjs/overlays/router-app/src/app/api/health/route.js +10 -0
- package/stacks/nextjs/overlays/router-app/src/app/layout.js +16 -0
- package/stacks/nextjs/overlays/router-app/src/app/page.js +19 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/_app.js +7 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/_document.js +13 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/api/health.js +8 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/index.js +27 -0
- package/stacks/nextjs/stack.json +257 -0
- package/stacks/node-express/overlays/auth/src/controllers/authController.js +53 -0
- package/stacks/node-express/overlays/auth/src/middlewares/auth.js +36 -0
- package/stacks/node-express/overlays/auth/src/routes/authRoutes.js +16 -0
- package/stacks/node-express/overlays/common/.env.example +5 -0
- package/stacks/node-express/overlays/common/public/index.html +31 -0
- package/stacks/node-express/overlays/common/src/server.js +32 -0
- package/stacks/node-express/overlays/db/mongodb/src/db.js +13 -0
- package/stacks/node-express/overlays/db/mssql/src/db.js +22 -0
- package/stacks/node-express/overlays/db/mysql/src/db.js +22 -0
- package/stacks/node-express/stack.json +165 -0
- package/templates/dotnet-bootstrap-mssql/Controllers/AuthController.cs +74 -0
- package/templates/dotnet-bootstrap-mssql/Controllers/ProductsController.cs +33 -0
- package/templates/dotnet-bootstrap-mssql/Data/ApplicationDbContext.cs +24 -0
- package/templates/dotnet-bootstrap-mssql/Models/Product.cs +10 -0
- package/templates/dotnet-core/Controllers/AuthController.cs +74 -0
- package/templates/laravel-full/app/Http/Controllers/AuthController.php +79 -0
- package/templates/laravel-full/app/Http/Controllers/HomeController.php +22 -0
- package/templates/laravel-full/app/Models/User.php +49 -0
- package/templates/laravel-full/artisan +22 -0
- package/templates/laravel-full/bootstrap/app.php +21 -0
- package/templates/laravel-full/config/database.php +54 -0
- package/templates/laravel-full/database/migrations/2024_01_01_000001_create_users_table.php +27 -0
- package/templates/laravel-full/public/index.php +17 -0
- package/templates/laravel-full/resources/css/app.css +3 -0
- package/templates/laravel-full/resources/js/Pages/Home.vue +76 -0
- package/templates/laravel-full/resources/js/app.js +21 -0
- package/templates/laravel-full/resources/js/bootstrap.js +3 -0
- package/templates/laravel-full/resources/views/app.blade.php +15 -0
- package/templates/laravel-full/routes/api.php +8 -0
- package/templates/laravel-full/routes/console.php +7 -0
- package/templates/laravel-full/routes/web.php +24 -0
- package/templates/laravel-full/tailwind.config.js +12 -0
- package/templates/laravel-full/vite.config.js +20 -0
- package/templates/laravel-vue/app/Http/Controllers/Auth/AuthenticatedSessionController.php +43 -0
- package/templates/laravel-vue-mysql/app/Http/Controllers/HomeController.php +25 -0
- package/templates/laravel-vue-mysql/resources/js/Pages/Home.vue +70 -0
- package/templates/nextjs/src/app/api/auth/login/route.js +28 -0
- package/templates/nextjs-mongodb/src/app/api/health/route.js +17 -0
- package/templates/nextjs-mongodb/src/lib/mongodb.js +18 -0
- package/templates/nextjs-mssql/src/app/api/health/route.js +24 -0
- package/templates/nextjs-mssql/src/lib/mssql.js +38 -0
- package/templates/node-express/src/controllers/authController.js +53 -0
- package/templates/node-express/src/middlewares/auth.js +36 -0
- package/templates/node-express/src/routes/authRoutes.js +16 -0
- package/templates/node-mongodb/src/controllers/userController.js +30 -0
- package/templates/node-mongodb/src/middlewares/errorHandler.js +8 -0
- package/templates/node-mongodb/src/models/User.js +23 -0
- package/templates/node-mongodb/src/routes/api.js +9 -0
- package/templates/raw-php-mysql/app/Controllers/AuthController.php +73 -0
- package/templates/raw-php-mysql/app/Controllers/HomeController.php +65 -0
- package/templates/raw-php-mysql/app/Models/User.php +60 -0
- package/templates/raw-php-mysql/app/Views/404.php +15 -0
- package/templates/raw-php-mysql/app/Views/auth/login.php +66 -0
- package/templates/raw-php-mysql/app/Views/auth/register.php +71 -0
- package/templates/raw-php-mysql/app/Views/dashboard.php +50 -0
- package/templates/raw-php-mysql/app/Views/home.php +83 -0
- package/templates/raw-php-mysql/config/Auth.php +62 -0
- package/templates/raw-php-mysql/config/Database.php +100 -0
- package/templates/raw-php-mysql/config/Env.php +30 -0
- package/templates/raw-php-mysql/config/Middleware.php +53 -0
- package/templates/raw-php-mysql/config/QueryBuilder.php +109 -0
- package/templates/raw-php-mysql/config/Router.php +33 -0
- package/templates/raw-php-mysql/public/index.php +57 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "node-express",
|
|
3
|
+
"name": "Node.js + Express",
|
|
4
|
+
"defaultPort": 5000,
|
|
5
|
+
"databases": [
|
|
6
|
+
"mysql",
|
|
7
|
+
"mongodb",
|
|
8
|
+
"mssql"
|
|
9
|
+
],
|
|
10
|
+
"stylings": [
|
|
11
|
+
"tailwind",
|
|
12
|
+
"bootstrap",
|
|
13
|
+
"vanilla"
|
|
14
|
+
],
|
|
15
|
+
"nextSteps": [
|
|
16
|
+
"npm run dev"
|
|
17
|
+
],
|
|
18
|
+
"versions": {
|
|
19
|
+
"source": "npm",
|
|
20
|
+
"package": "express",
|
|
21
|
+
"minMajor": 4,
|
|
22
|
+
"testedUpTo": 5,
|
|
23
|
+
"offline": [
|
|
24
|
+
5,
|
|
25
|
+
4
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"requires": [
|
|
29
|
+
{
|
|
30
|
+
"cmd": "node",
|
|
31
|
+
"name": "Node.js",
|
|
32
|
+
"install": "https://nodejs.org"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"cmd": "npm",
|
|
36
|
+
"name": "npm",
|
|
37
|
+
"install": "Ships with Node.js"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"vars": [
|
|
41
|
+
{
|
|
42
|
+
"name": "AUTH_REQUIRE",
|
|
43
|
+
"when": {
|
|
44
|
+
"auth": true
|
|
45
|
+
},
|
|
46
|
+
"value": "const authRoutes = require('./routes/authRoutes');"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "AUTH_MOUNT",
|
|
50
|
+
"when": {
|
|
51
|
+
"auth": true
|
|
52
|
+
},
|
|
53
|
+
"value": "app.use('/api/auth', authRoutes);"
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"steps": [
|
|
57
|
+
{
|
|
58
|
+
"label": "Creating package.json",
|
|
59
|
+
"run": [
|
|
60
|
+
"npm",
|
|
61
|
+
"init",
|
|
62
|
+
"-y"
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"label": "Installing Express {{VERSION}}.x and core packages",
|
|
67
|
+
"run": [
|
|
68
|
+
"npm",
|
|
69
|
+
"install",
|
|
70
|
+
"express@{{VERSION}}",
|
|
71
|
+
"dotenv",
|
|
72
|
+
"cors"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"when": {
|
|
77
|
+
"database": "mongodb"
|
|
78
|
+
},
|
|
79
|
+
"run": [
|
|
80
|
+
"npm",
|
|
81
|
+
"install",
|
|
82
|
+
"mongoose"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"when": {
|
|
87
|
+
"database": "mysql"
|
|
88
|
+
},
|
|
89
|
+
"run": [
|
|
90
|
+
"npm",
|
|
91
|
+
"install",
|
|
92
|
+
"mysql2"
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"when": {
|
|
97
|
+
"database": "mssql"
|
|
98
|
+
},
|
|
99
|
+
"run": [
|
|
100
|
+
"npm",
|
|
101
|
+
"install",
|
|
102
|
+
"mssql"
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"when": {
|
|
107
|
+
"auth": true
|
|
108
|
+
},
|
|
109
|
+
"run": [
|
|
110
|
+
"npm",
|
|
111
|
+
"install",
|
|
112
|
+
"jsonwebtoken",
|
|
113
|
+
"bcryptjs"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"json": "package.json",
|
|
118
|
+
"merge": {
|
|
119
|
+
"description": "{{APP_DESC}}",
|
|
120
|
+
"author": "{{AUTHOR}}",
|
|
121
|
+
"main": "src/server.js",
|
|
122
|
+
"scripts": {
|
|
123
|
+
"start": "node src/server.js",
|
|
124
|
+
"dev": "node --watch src/server.js"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"label": "Applying BoilerCraft overlay",
|
|
130
|
+
"copy": "overlays/common"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"when": {
|
|
134
|
+
"database": "mongodb"
|
|
135
|
+
},
|
|
136
|
+
"copy": "overlays/db/mongodb"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"when": {
|
|
140
|
+
"database": "mysql"
|
|
141
|
+
},
|
|
142
|
+
"copy": "overlays/db/mysql"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"when": {
|
|
146
|
+
"database": "mssql"
|
|
147
|
+
},
|
|
148
|
+
"copy": "overlays/db/mssql"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"when": {
|
|
152
|
+
"auth": true
|
|
153
|
+
},
|
|
154
|
+
"copy": "overlays/auth"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"write": "public/theme.css",
|
|
158
|
+
"content": "{{THEME_CSS}}"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"write": "public/theme.js",
|
|
162
|
+
"content": "{{THEME_JS}}"
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
using Microsoft.AspNetCore.Mvc;
|
|
2
|
+
using Microsoft.IdentityModel.Tokens;
|
|
3
|
+
using System.IdentityModel.Tokens.Jwt;
|
|
4
|
+
using System.Security.Claims;
|
|
5
|
+
using System.Text;
|
|
6
|
+
|
|
7
|
+
namespace DotNetBootstrapMssql.Controllers
|
|
8
|
+
{
|
|
9
|
+
[ApiController]
|
|
10
|
+
[Route("api/[controller]")]
|
|
11
|
+
public class AuthController : ControllerBase
|
|
12
|
+
{
|
|
13
|
+
public static readonly string SecretKey = "SuperSecret_Key_For_DotNetCore_Auth_Token_2026!";
|
|
14
|
+
|
|
15
|
+
public class LoginDto
|
|
16
|
+
{
|
|
17
|
+
public string Email { get; set; } = string.Empty;
|
|
18
|
+
public string Password { get; set; } = string.Empty;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public class RegisterDto
|
|
22
|
+
{
|
|
23
|
+
public string Name { get; set; } = string.Empty;
|
|
24
|
+
public string Email { get; set; } = string.Empty;
|
|
25
|
+
public string Password { get; set; } = string.Empty;
|
|
26
|
+
public string Role { get; set; } = "user";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
[HttpPost("login")]
|
|
30
|
+
public IActionResult Login([FromBody] LoginDto dto)
|
|
31
|
+
{
|
|
32
|
+
// Demo credentials verification
|
|
33
|
+
if (dto.Email == "admin@example.com" && dto.Password == "admin123")
|
|
34
|
+
{
|
|
35
|
+
var token = GenerateJwtToken("1", "Admin User", dto.Email, "admin");
|
|
36
|
+
return Ok(new { success = true, token, role = "admin" });
|
|
37
|
+
}
|
|
38
|
+
else if (!string.IsNullOrEmpty(dto.Email) && !string.IsNullOrEmpty(dto.Password))
|
|
39
|
+
{
|
|
40
|
+
var token = GenerateJwtToken("2", "Standard User", dto.Email, "user");
|
|
41
|
+
return Ok(new { success = true, token, role = "user" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return Unauthorized(new { success = false, error = "Invalid credentials" });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
[HttpPost("register")]
|
|
48
|
+
public IActionResult Register([FromBody] RegisterDto dto)
|
|
49
|
+
{
|
|
50
|
+
var token = GenerateJwtToken("3", dto.Name, dto.Email, dto.Role);
|
|
51
|
+
return Ok(new { success = true, token, user = dto });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private string GenerateJwtToken(string id, string name, string email, string role)
|
|
55
|
+
{
|
|
56
|
+
var tokenHandler = new JwtSecurityTokenHandler();
|
|
57
|
+
var key = Encoding.ASCII.GetBytes(SecretKey);
|
|
58
|
+
var tokenDescriptor = new SecurityTokenDescriptor
|
|
59
|
+
{
|
|
60
|
+
Subject = new ClaimsIdentity(new[]
|
|
61
|
+
{
|
|
62
|
+
new Claim(ClaimTypes.NameIdentifier, id),
|
|
63
|
+
new Claim(ClaimTypes.Name, name),
|
|
64
|
+
new Claim(ClaimTypes.Email, email),
|
|
65
|
+
new Claim(ClaimTypes.Role, role)
|
|
66
|
+
}),
|
|
67
|
+
Expires = DateTime.UtcNow.AddDays(7),
|
|
68
|
+
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
|
|
69
|
+
};
|
|
70
|
+
var token = tokenHandler.CreateToken(tokenDescriptor);
|
|
71
|
+
return tokenHandler.WriteToken(token);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
using Microsoft.AspNetCore.Mvc;
|
|
2
|
+
using Microsoft.EntityFrameworkCore;
|
|
3
|
+
using DotNetBootstrapMssql.Data;
|
|
4
|
+
using DotNetBootstrapMssql.Models;
|
|
5
|
+
|
|
6
|
+
namespace DotNetBootstrapMssql.Controllers
|
|
7
|
+
{
|
|
8
|
+
[ApiController]
|
|
9
|
+
[Route("api/[controller]")]
|
|
10
|
+
public class ProductsController : ControllerBase
|
|
11
|
+
{
|
|
12
|
+
private readonly ApplicationDbContext _context;
|
|
13
|
+
|
|
14
|
+
public ProductsController(ApplicationDbContext context)
|
|
15
|
+
{
|
|
16
|
+
_context = context;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
[HttpGet]
|
|
20
|
+
public async Task<ActionResult<IEnumerable<Product>>> GetProducts()
|
|
21
|
+
{
|
|
22
|
+
return await _context.Products.ToListAsync();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[HttpPost]
|
|
26
|
+
public async Task<ActionResult<Product>> PostProduct(Product product)
|
|
27
|
+
{
|
|
28
|
+
_context.Products.Add(product);
|
|
29
|
+
await _context.SaveChangesAsync();
|
|
30
|
+
return CreatedAtAction(nameof(GetProducts), new { id = product.Id }, product);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
using Microsoft.EntityFrameworkCore;
|
|
2
|
+
using DotNetBootstrapMssql.Models;
|
|
3
|
+
|
|
4
|
+
namespace DotNetBootstrapMssql.Data
|
|
5
|
+
{
|
|
6
|
+
public class ApplicationDbContext : DbContext
|
|
7
|
+
{
|
|
8
|
+
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
|
|
9
|
+
{
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public DbSet<Product> Products { get; set; }
|
|
13
|
+
|
|
14
|
+
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
15
|
+
{
|
|
16
|
+
base.OnModelCreating(modelBuilder);
|
|
17
|
+
|
|
18
|
+
// Seed initial sample product
|
|
19
|
+
modelBuilder.Entity<Product>().HasData(
|
|
20
|
+
new Product { Id = 1, Name = "Starter Kit", Price = 99.99m, Description = "Built with BoilerCraft Studio" }
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
using Microsoft.AspNetCore.Mvc;
|
|
2
|
+
using Microsoft.IdentityModel.Tokens;
|
|
3
|
+
using System.IdentityModel.Tokens.Jwt;
|
|
4
|
+
using System.Security.Claims;
|
|
5
|
+
using System.Text;
|
|
6
|
+
|
|
7
|
+
namespace DotNetCore.Controllers
|
|
8
|
+
{
|
|
9
|
+
[ApiController]
|
|
10
|
+
[Route("api/[controller]")]
|
|
11
|
+
public class AuthController : ControllerBase
|
|
12
|
+
{
|
|
13
|
+
public static readonly string SecretKey = "SuperSecret_Key_For_DotNetCore_Auth_Token_2026!";
|
|
14
|
+
|
|
15
|
+
public class LoginDto
|
|
16
|
+
{
|
|
17
|
+
public string Email { get; set; } = string.Empty;
|
|
18
|
+
public string Password { get; set; } = string.Empty;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public class RegisterDto
|
|
22
|
+
{
|
|
23
|
+
public string Name { get; set; } = string.Empty;
|
|
24
|
+
public string Email { get; set; } = string.Empty;
|
|
25
|
+
public string Password { get; set; } = string.Empty;
|
|
26
|
+
public string Role { get; set; } = "user";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
[HttpPost("login")]
|
|
30
|
+
public IActionResult Login([FromBody] LoginDto dto)
|
|
31
|
+
{
|
|
32
|
+
// Demo credentials verification
|
|
33
|
+
if (dto.Email == "admin@example.com" && dto.Password == "admin123")
|
|
34
|
+
{
|
|
35
|
+
var token = GenerateJwtToken("1", "Admin User", dto.Email, "admin");
|
|
36
|
+
return Ok(new { success = true, token, role = "admin" });
|
|
37
|
+
}
|
|
38
|
+
else if (!string.IsNullOrEmpty(dto.Email) && !string.IsNullOrEmpty(dto.Password))
|
|
39
|
+
{
|
|
40
|
+
var token = GenerateJwtToken("2", "Standard User", dto.Email, "user");
|
|
41
|
+
return Ok(new { success = true, token, role = "user" });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return Unauthorized(new { success = false, error = "Invalid credentials" });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
[HttpPost("register")]
|
|
48
|
+
public IActionResult Register([FromBody] RegisterDto dto)
|
|
49
|
+
{
|
|
50
|
+
var token = GenerateJwtToken("3", dto.Name, dto.Email, dto.Role);
|
|
51
|
+
return Ok(new { success = true, token, user = dto });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private string GenerateJwtToken(string id, string name, string email, string role)
|
|
55
|
+
{
|
|
56
|
+
var tokenHandler = new JwtSecurityTokenHandler();
|
|
57
|
+
var key = Encoding.ASCII.GetBytes(SecretKey);
|
|
58
|
+
var tokenDescriptor = new SecurityTokenDescriptor
|
|
59
|
+
{
|
|
60
|
+
Subject = new ClaimsIdentity(new[]
|
|
61
|
+
{
|
|
62
|
+
new Claim(ClaimTypes.NameIdentifier, id),
|
|
63
|
+
new Claim(ClaimTypes.Name, name),
|
|
64
|
+
new Claim(ClaimTypes.Email, email),
|
|
65
|
+
new Claim(ClaimTypes.Role, role)
|
|
66
|
+
}),
|
|
67
|
+
Expires = DateTime.UtcNow.AddDays(7),
|
|
68
|
+
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
|
|
69
|
+
};
|
|
70
|
+
var token = tokenHandler.CreateToken(tokenDescriptor);
|
|
71
|
+
return tokenHandler.WriteToken(token);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
use App\Models\User;
|
|
6
|
+
use Illuminate\Http\Request;
|
|
7
|
+
use Illuminate\Support\Facades\Auth;
|
|
8
|
+
use Illuminate\Support\Facades\Hash;
|
|
9
|
+
use Illuminate\Validation\ValidationException;
|
|
10
|
+
|
|
11
|
+
class AuthController extends Controller
|
|
12
|
+
{
|
|
13
|
+
/**
|
|
14
|
+
* Handle user login.
|
|
15
|
+
*/
|
|
16
|
+
public function login(Request $request)
|
|
17
|
+
{
|
|
18
|
+
$credentials = $request->validate([
|
|
19
|
+
'email' => ['required', 'email'],
|
|
20
|
+
'password' => ['required'],
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
if (Auth::attempt($credentials, $request->boolean('remember'))) {
|
|
24
|
+
$request->session()->regenerate();
|
|
25
|
+
|
|
26
|
+
return response()->json([
|
|
27
|
+
'success' => true,
|
|
28
|
+
'message' => 'Logged in successfully.',
|
|
29
|
+
'user' => Auth::user(),
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
throw ValidationException::withMessages([
|
|
34
|
+
'email' => ['The provided credentials do not match our records.'],
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Handle user registration.
|
|
40
|
+
*/
|
|
41
|
+
public function register(Request $request)
|
|
42
|
+
{
|
|
43
|
+
$validated = $request->validate([
|
|
44
|
+
'name' => ['required', 'string', 'max:255'],
|
|
45
|
+
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
|
46
|
+
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
$user = User::create([
|
|
50
|
+
'name' => $validated['name'],
|
|
51
|
+
'email' => $validated['email'],
|
|
52
|
+
'password' => Hash::make($validated['password']),
|
|
53
|
+
'role' => 'user',
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
Auth::login($user);
|
|
57
|
+
|
|
58
|
+
return response()->json([
|
|
59
|
+
'success' => true,
|
|
60
|
+
'message' => 'Registration successful.',
|
|
61
|
+
'user' => $user,
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Log the user out of the application.
|
|
67
|
+
*/
|
|
68
|
+
public function logout(Request $request)
|
|
69
|
+
{
|
|
70
|
+
Auth::logout();
|
|
71
|
+
$request->session()->invalidate();
|
|
72
|
+
$request->session()->regenerateToken();
|
|
73
|
+
|
|
74
|
+
return response()->json([
|
|
75
|
+
'success' => true,
|
|
76
|
+
'message' => 'Logged out successfully.',
|
|
77
|
+
]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Http\Controllers;
|
|
4
|
+
|
|
5
|
+
use Inertia\Inertia;
|
|
6
|
+
use Inertia\Response;
|
|
7
|
+
use Illuminate\Http\Request;
|
|
8
|
+
|
|
9
|
+
class HomeController extends Controller
|
|
10
|
+
{
|
|
11
|
+
public function index(): Response
|
|
12
|
+
{
|
|
13
|
+
return Inertia::render('Home', [
|
|
14
|
+
'appName' => '{{APP_TITLE}}',
|
|
15
|
+
'description' => '{{APP_DESC}}',
|
|
16
|
+
'author' => '{{AUTHOR}}',
|
|
17
|
+
'framework' => 'Laravel 11.x',
|
|
18
|
+
'frontend' => 'Vue 3 + Vite',
|
|
19
|
+
'database' => '{{DB_TYPE}}'
|
|
20
|
+
]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace App\Models;
|
|
4
|
+
|
|
5
|
+
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
|
6
|
+
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
7
|
+
use Illuminate\Foundation\Auth\User as Authenticatable;
|
|
8
|
+
use Illuminate\Notifications\Notifiable;
|
|
9
|
+
use Laravel\Sanctum\HasApiTokens;
|
|
10
|
+
|
|
11
|
+
class User extends Authenticatable
|
|
12
|
+
{
|
|
13
|
+
use HasApiTokens, HasFactory, Notifiable;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The attributes that are mass assignable.
|
|
17
|
+
*
|
|
18
|
+
* @var list<string>
|
|
19
|
+
*/
|
|
20
|
+
protected $fillable = [
|
|
21
|
+
'name',
|
|
22
|
+
'email',
|
|
23
|
+
'password',
|
|
24
|
+
'role',
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The attributes that should be hidden for serialization.
|
|
29
|
+
*
|
|
30
|
+
* @var list<string>
|
|
31
|
+
*/
|
|
32
|
+
protected $hidden = [
|
|
33
|
+
'password',
|
|
34
|
+
'remember_token',
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get the attributes that should be cast.
|
|
39
|
+
*
|
|
40
|
+
* @return array<string, string>
|
|
41
|
+
*/
|
|
42
|
+
protected function casts(): array
|
|
43
|
+
{
|
|
44
|
+
return [
|
|
45
|
+
'email_verified_at' => 'datetime',
|
|
46
|
+
'password' => 'hashed',
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env php
|
|
2
|
+
<?php
|
|
3
|
+
|
|
4
|
+
use Symfony\Component\Console\Input\ArgvInput;
|
|
5
|
+
|
|
6
|
+
define('LARAVEL_START', microtime(true));
|
|
7
|
+
|
|
8
|
+
// Register the Composer Autoloader...
|
|
9
|
+
if (file_exists($maintenance = __DIR__.'/storage/framework/maintenance.php')) {
|
|
10
|
+
require $maintenance;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Check if vendor exists
|
|
14
|
+
if (file_exists(__DIR__.'/vendor/autoload.php')) {
|
|
15
|
+
require __DIR__.'/vendor/autoload.php';
|
|
16
|
+
$app = require_once __DIR__.'/bootstrap/app.php';
|
|
17
|
+
$status = $app->handleCommand(new ArgvInput);
|
|
18
|
+
exit($status);
|
|
19
|
+
} else {
|
|
20
|
+
echo "⚠️ Vendor folder missing. Please run: composer install\n";
|
|
21
|
+
exit(1);
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Foundation\Application;
|
|
4
|
+
use Illuminate\Foundation\Configuration\Exceptions;
|
|
5
|
+
use Illuminate\Foundation\Configuration\Middleware;
|
|
6
|
+
|
|
7
|
+
return Application::configure(basePath: dirname(__DIR__))
|
|
8
|
+
->withRouting(
|
|
9
|
+
web: __DIR__.'/../routes/web.php',
|
|
10
|
+
api: __DIR__.'/../routes/api.php',
|
|
11
|
+
commands: __DIR__.'/../routes/console.php',
|
|
12
|
+
health: '/up',
|
|
13
|
+
)
|
|
14
|
+
->withMiddleware(function (Middleware $middleware) {
|
|
15
|
+
$middleware->web(append: [
|
|
16
|
+
\App\Http\Middleware\HandleInertiaRequests::class,
|
|
17
|
+
]);
|
|
18
|
+
})
|
|
19
|
+
->withExceptions(function (Exceptions $exceptions) {
|
|
20
|
+
//
|
|
21
|
+
})->create();
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
return [
|
|
4
|
+
'default' => env('DB_CONNECTION', '{{DB_TYPE}}'),
|
|
5
|
+
|
|
6
|
+
'connections' => [
|
|
7
|
+
'sqlite' => [
|
|
8
|
+
'driver' => 'sqlite',
|
|
9
|
+
'url' => env('DB_URL'),
|
|
10
|
+
'database' => env('DB_DATABASE', database_path('database.sqlite')),
|
|
11
|
+
'prefix' => '',
|
|
12
|
+
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
|
|
13
|
+
],
|
|
14
|
+
|
|
15
|
+
'mysql' => [
|
|
16
|
+
'driver' => 'mysql',
|
|
17
|
+
'url' => env('DB_URL'),
|
|
18
|
+
'host' => env('DB_HOST', '127.0.0.1'),
|
|
19
|
+
'port' => env('DB_PORT', '3306'),
|
|
20
|
+
'database' => env('DB_DATABASE', '{{DB_NAME}}'),
|
|
21
|
+
'username' => env('DB_USERNAME', 'root'),
|
|
22
|
+
'password' => env('DB_PASSWORD', ''),
|
|
23
|
+
'unix_socket' => env('DB_SOCKET', ''),
|
|
24
|
+
'charset' => env('DB_CHARSET', 'utf8mb4'),
|
|
25
|
+
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
|
|
26
|
+
'prefix' => '',
|
|
27
|
+
'prefix_indexes' => true,
|
|
28
|
+
'strict' => true,
|
|
29
|
+
'engine' => null,
|
|
30
|
+
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
|
31
|
+
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
|
32
|
+
]) : [],
|
|
33
|
+
],
|
|
34
|
+
|
|
35
|
+
'sqlsrv' => [
|
|
36
|
+
'driver' => 'sqlsrv',
|
|
37
|
+
'url' => env('DB_URL'),
|
|
38
|
+
'host' => env('DB_HOST', 'localhost'),
|
|
39
|
+
'port' => env('DB_PORT', '1433'),
|
|
40
|
+
'database' => env('DB_DATABASE', '{{DB_NAME}}'),
|
|
41
|
+
'username' => env('DB_USERNAME', 'sa'),
|
|
42
|
+
'password' => env('DB_PASSWORD', 'YourStrong@Password'),
|
|
43
|
+
'charset' => env('DB_CHARSET', 'utf8'),
|
|
44
|
+
'prefix' => '',
|
|
45
|
+
'prefix_indexes' => true,
|
|
46
|
+
'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'true'),
|
|
47
|
+
],
|
|
48
|
+
],
|
|
49
|
+
|
|
50
|
+
'migrations' => [
|
|
51
|
+
'table' => 'migrations',
|
|
52
|
+
'update_date_on_publish' => true,
|
|
53
|
+
],
|
|
54
|
+
];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Database\Migrations\Migration;
|
|
4
|
+
use Illuminate\Database\Schema\Blueprint;
|
|
5
|
+
use Illuminate\Support\Facades\Schema;
|
|
6
|
+
|
|
7
|
+
return new class extends Migration
|
|
8
|
+
{
|
|
9
|
+
public function up(): void
|
|
10
|
+
{
|
|
11
|
+
Schema::create('users', function (Blueprint $table) {
|
|
12
|
+
$table->id();
|
|
13
|
+
$table->string('name');
|
|
14
|
+
$table->string('email')->unique();
|
|
15
|
+
$table->timestamp('email_verified_at')->nullable();
|
|
16
|
+
$table->string('password');
|
|
17
|
+
$table->string('role')->default('user');
|
|
18
|
+
$table->rememberToken();
|
|
19
|
+
$table->timestamps();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public function down(): void
|
|
24
|
+
{
|
|
25
|
+
Schema::dropIfExists('users');
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
use Illuminate\Http\Request;
|
|
4
|
+
|
|
5
|
+
define('LARAVEL_START', microtime(true));
|
|
6
|
+
|
|
7
|
+
// Determine if the application is in maintenance mode...
|
|
8
|
+
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
|
9
|
+
require $maintenance;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Register the Composer autoloader...
|
|
13
|
+
require __DIR__.'/../vendor/autoload.php';
|
|
14
|
+
|
|
15
|
+
// Bootstrap Laravel and handle the request...
|
|
16
|
+
(require_once __DIR__.'/../bootstrap/app.php')
|
|
17
|
+
->handleRequest(Request::capture());
|