conflicts solve

This commit is contained in:
sayliraut
2025-03-20 12:02:37 +05:30
7 changed files with 604 additions and 8 deletions

View File

@@ -5,12 +5,19 @@ namespace App\Http\Controllers\APIS\AdminApi;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\CreateUserRequest;
use App\Mail\Admin\UserCreatedMail;
use App\Models\User;
use App\Services\AdminService;
use Exception;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Auth;
class UsersController extends Controller
{
@@ -70,13 +77,32 @@ class UsersController extends Controller
$user->last_login_ts = $request->last_login_ts;
$user->save();
return jsonResponseWithSuccessMessage(__('auth.data_fetched_successfully'), $response, 200);
} catch (QueryException $e) {
$randomToken = Str::random(64);
$activationLink = url("/apia/activate/{$user->id}?token={$randomToken}");
$mail = Mail::to($user->email)->send(new UserCreatedMail($user, $activationLink));
return response()->json([
'message' => __('auth.data_fetched_successfully'),
'user_id' => $user->id,
'activation_link' => $activationLink,
'token' => $randomToken,
'data' => $response
], 200);
} catch (QueryException $e) {
Log::error('Error in creating User ' . $e->getMessage());
return jsonResponseWithErrorMessageApi(__('auth.something went wrong'), 401);
}
}
public function list()
{
try {
@@ -131,5 +157,267 @@ class UsersController extends Controller
}
}
// public function activate(Request $request, $id)
// {
// Log::info('Full Request URL: ' . $request->fullUrl());
// try {
// $user = User::find($id);
// if (!$user) {
// Log::error("User not found for ID: {$id}");
// return response()->json([
// 'status' => false,
// 'message' => 'User not found.'
// ], 404);
// }
// $token = $request->query('token');
// if (!$token) {
// Log::error("Token missing for User ID: {$id}");
// return response()->json([
// 'status' => false,
// 'message' => 'Invalid activation link.'
// ], 401);
// }
// // Validate password input
// $validated = $request->validate([
// 'password' => 'required|min:6|confirmed'
// ]);
// // Update the user's password locally
// $user->password = Hash::make($validated['password']);
// $user->save();
// // Use the activateUser function to activate in ThingsBoard
// $this->adminService->activateUser($user, $validated['password'], $token);
// Log::info("User ID: {$id} activated successfully.");
// return response()->json([
// 'status' => true,
// 'message' => 'User activated and password set successfully in Laravel and ThingsBoard!',
// 'user_id' => $user->id
// ], 200);
// } catch (ValidationException $e) {
// Log::error("Validation error for User ID: {$id}. Exception: " . $e->getMessage());
// return response()->json([
// 'status' => false,
// 'message' => 'Validation error.',
// 'errors' => $e->errors()
// ], 422);
// } catch (\Exception $e) {
// Log::error("Error activating user ID: {$id}. Exception: " . $e->getMessage());
// return response()->json([
// 'status' => false,
// 'message' => 'An error occurred. Please try again later.',
// 'error' => $e->getMessage()
// ], 500);
// }
// }
public function activate(Request $request, $id)
{
Log::info('Full Request URL: ' . $request->fullUrl());
try {
$user = User::find($id);
if (!$user) {
Log::error("User not found for ID: {$id}");
return response()->json([
'status' => false,
'message' => 'User not found.'
], 404);
}
$token = $request->query('token');
if (!$token) {
Log::error("Token missing for User ID: {$id}");
return response()->json([
'status' => false,
'message' => 'Invalid activation link.'
], 401);
}
// ✅ Validate password input
$validated = $request->validate([
'password' => 'required|min:6|confirmed'
]);
// ✅ Update the user's password locally
$user->password = Hash::make($validated['password']);
$user->save();
Log::info("User ID: {$id} activated successfully in Laravel.");
return response()->json([
'status' => true,
'message' => 'User activated and password set successfully in Laravel!',
'user_id' => $user->id
], 200);
} catch (ValidationException $e) {
Log::error("Validation error for User ID: {$id}. Exception: " . $e->getMessage());
return response()->json([
'status' => false,
'message' => 'Validation error.',
'errors' => $e->errors()
], 422);
} catch (\Exception $e) {
Log::error("Error activating user ID: {$id}. Exception: " . $e->getMessage());
return response()->json([
'status' => false,
'message' => 'An error occurred. Please try again later.',
'error' => $e->getMessage()
], 500);
}
}
// public function autoLogin(Request $request)
// {
// $request->validate([
// 'email' => 'required|email'
// ]);
// $email = $request->email;
// $user = User::where('email', $email)->first();
// if (!$user) {
// return response()->json([
// 'status' => false,
// 'message' => 'User not found in Laravel. Please register or verify your email.'
// ], 404);
// }
// Auth::login($user);
// $thingsboardUser = $this->adminService->getUserByEmail($email);
// if ($thingsboardUser) {
// $tbUserId = $thingsboardUser['id']['id'];
// $thingsboardDashboardUrl = "http://your-thingsboard-domain.com/dashboard/{$tbUserId}";
// } else {
// $thingsboardDashboardUrl = null;
// }
// return response()->json([
// 'status' => true,
// 'message' => 'User found, redirecting to dashboards...',
// 'laravel_dashboard_url' => url("/dashboard/{$user->id}"),
// 'thingsboard_dashboard_url' => $thingsboardDashboardUrl
// ], 200);
// }
// public function loginUser(Request $request)
// {
// $email = $request->input('email');
// if (!$email) {
// return response()->json([
// 'status' => false,
// 'message' => 'Email is required.'
// ], 400);
// }
// $localResponse = null;
// $thingsboardResponse = null;
// // ✅ Check in local database
// $user = User::where('email', $email)->first();
// if ($user) {
// $localResponse = [
// 'status' => true,
// 'message' => 'Login successful (Local). Redirecting to Local dashboard...',
// 'user_id' => $user->id,
// 'email' => $email,
// 'dashboard_url' => url('/dashboard') // Local dashboard URL
// ];
// } else {
// $localResponse = [
// 'status' => false,
// 'message' => 'User not found in Local database.'
// ];
// }
// // ✅ Check in ThingsBoard
// $thingsboardResponse = $this->adminService->getUserByIdThingsBoard($email);
// if ($thingsboardResponse['status']) {
// $thingsboardUser = $thingsboardResponse['user'];
// $thingsboardResponse = [
// 'status' => true,
// 'message' => 'Login successful (ThingsBoard). Redirecting to ThingsBoard dashboard...',
// 'user_id' => $thingsboardUser['id']['id'],
// 'email' => $email,
// 'dashboard_url' => $thingsboardResponse['dashboard_url']
// ];
// } else {
// $thingsboardResponse = [
// 'status' => false,
// 'message' => 'User not found in ThingsBoard.'
// ];
// }
// // ✅ Return both responses
// return response()->json([
// 'local' => $localResponse,
// 'thingsboard' => $thingsboardResponse
// ], 200);
// }
public function loginUser(Request $request)
{
$email = $request->input('email');
if (!$email) {
return response()->json([
'status' => false,
'message' => 'Email is required.'
], 400);
}
$localResponse = null;
$thingsboardResponse = null;
// ✅ Check in Local database
$user = User::where('email', $email)->first();
if ($user) {
$localResponse = [
'status' => true,
'message' => 'Login successful (Local). Redirecting to Local dashboard...',
'user_id' => $user->id,
'email' => $email,
'dashboard_url' => url('/dashboard')
];
} else {
$localResponse = [
'status' => false,
'message' => 'User not found in Local database.'
];
}
// ✅ Fetch ThingsBoard user by email, then by ID
$thingsboardResponse = $this->adminService->getUserByEmailThingsBoard($email);
// ✅ Return both responses
return response()->json([
'local' => $localResponse,
'thingsboard' => $thingsboardResponse
], 200);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Mail\Admin;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class UserCreatedMail extends Mailable
{
use Queueable, SerializesModels;
public $user;
public $activationLink;
public function __construct($user, $activationLink)
{
$this->user = $user;
$this->activationLink = $activationLink;
}
public function build()
{
return $this->subject('Activate Your Account')
->view('Mails.user_created')
->with([
'user' => $this->user,
'activationLink' => $this->activationLink
]);
}
}

View File

@@ -2,10 +2,12 @@
namespace App\Services;
use App\Models\User;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
use Exception;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class AdminService
@@ -173,6 +175,78 @@ class AdminService
throw new Exception('Failed to create user: ' . $response->body());
}
// public function createOrUpdateUser(array $data)
// {
// $token = $this->getToken();
// // First, check if the user exists in ThingsBoard by email
// $email = $data['email'];
// // ✅ Fetch ThingsBoard ID by email
// $response = Http::withHeaders([
// 'Authorization' => "Bearer $token",
// 'accept' => 'application/json'
// ])->get("{$this->baseUrl}/api/users?pageSize=1&page=0&textSearch=$email");
// $userExists = false;
// $thingsboardUserId = null;
// if ($response->successful()) {
// $users = $response->json()['data'] ?? [];
// if (!empty($users)) {
// $userExists = true;
// $thingsboardUserId = $users[0]['id']['id'];
// }
// }
// // ✅ Prepare payload
// $payload = [
// 'email' => $data['email'] ?? 'default@example.com',
// 'tenantId' => [
// 'id' => $data['tenantId'] ?? '6e9b7fde-0ca0-4d19-9d2a-fba98e3e12a0',
// 'entityType' => 'TENANT'
// ],
// 'customerId' => [
// 'id' => $data['customerId'],
// 'entityType' => 'CUSTOMER'
// ],
// 'authority' => $data['authority'] ?? 'TENANT_ADMIN',
// 'name' => $data['name'] ?? 'John Doe',
// 'phone' => $data['phone'] ?? '1234567890',
// 'additionalInfo' => [
// 'description' => $data['description'] ?? 'User description'
// ]
// ];
// if ($userExists && $thingsboardUserId) {
// // ✅ Update existing user in ThingsBoard
// $response = Http::withHeaders([
// 'Authorization' => "Bearer $token",
// 'accept' => 'application/json',
// 'Content-Type' => 'application/json',
// ])->withBody(json_encode($payload), 'application/json')
// ->post("{$this->baseUrl}/api/user/{$thingsboardUserId}");
// } else {
// // ✅ Create new user in ThingsBoard
// $response = Http::withHeaders([
// 'Authorization' => "Bearer $token",
// 'accept' => 'application/json',
// 'Content-Type' => 'application/json',
// ])->withBody(json_encode($payload), 'application/json')
// ->post("{$this->baseUrl}/api/user");
// }
// if ($response->successful()) {
// return $response->json();
// } else {
// throw new Exception('Failed to create or update user: ' . $response->body());
// }
// }
public function listUsers()
@@ -192,24 +266,133 @@ class AdminService
}
public function deleteUser($userId)
{
public function deleteUser($userId)
{
try {
$token = $this->getToken();
// ✅ Make the DELETE request to ThingsBoard
$response = Http::withHeaders([
'Authorization' => "Bearer $token",
'accept' => 'application/json',
'Content-Type' => 'application/json',
])->delete("{$this->baseUrl}/api/user/{$userId}");
// Handle ThingsBoard API errors
// Handle API response
if ($response->failed()) {
Log::error('Failed to delete user: ' . $response->body());
// Return the ThingsBoard error message
return $response->json();
return response()->json([
'error' => true,
'message' => 'Failed to delete user from ThingsBoard',
'details' => $response->json()
], $response->status());
}
return $response->json();
// ✅ Return successful response
return response()->json([
'success' => true,
'message' => 'User deleted successfully',
'data' => $response->json()
], 200);
} catch (Exception $e) {
Log::error('Exception while deleting user: ' . $e->getMessage());
return response()->json([
'error' => true,
'message' => 'An error occurred while deleting the user',
], 500);
}
}
public function activateUser(User $user, string $password, string $activateToken)
{
try {
// Prepare the payload with the token and password
$payload = [
'activateToken' => $activateToken,
'password' => $password
];
$activationUrl = "{$this->baseUrl}/api/noauth/activate";
// Send the activation request
$response = Http::withHeaders([
'Content-Type' => 'application/json',
])->post($activationUrl, $payload);
if (!$response->successful()) {
Log::error("Failed to activate user in ThingsBoard. Error: " . $response->body());
throw new Exception('Failed to activate user: ' . $response->body());
}
Log::info("User activated successfully in ThingsBoard for User ID: {$user->id}");
} catch (\Exception $e) {
Log::error("Error activating user in ThingsBoard for User ID: {$user->id}. Exception: " . $e->getMessage());
throw $e;
}
}
public function getUserByEmailThingsBoard(string $email)
{
Log::info("Fetching ThingsBoard ID by email: $email");
$token = $this->getToken();
// First, fetch the ThingsBoard ID by email
$response = Http::withHeaders([
'Authorization' => "Bearer $token",
'accept' => 'application/json'
])->get("http://65.0.131.117:8080/api/users?pageSize=1&page=0&textSearch=$email");
if ($response->successful()) {
$data = $response->json()['data'] ?? [];
if (!empty($data)) {
$thingsboardUserId = $data[0]['id']['id'];
Log::info("Found ThingsBoard ID: $thingsboardUserId");
// Now fetch user by ID
$userResponse = Http::withHeaders([
'Authorization' => "Bearer $token",
'accept' => 'application/json'
])->get("http://65.0.131.117:8080/api/user/$thingsboardUserId");
if ($userResponse->successful()) {
return [
'status' => true,
'user' => $userResponse->json(),
'dashboard_url' => 'http://65.0.131.117:8080/dashboard'
];
} else {
Log::error("Failed to fetch user by ID. Status: " . $userResponse->status());
return [
'status' => false,
'message' => 'User not found in ThingsBoard by ID.'
];
}
}
}
Log::error("Failed to fetch ThingsBoard ID. Status: " . $response->status());
return [
'status' => false,
'message' => 'User not found in ThingsBoard by email.'
];
}
}

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('device_profile_master', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('device_profile_master');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('timeseries_key_master', function (Blueprint $table) {
$table->id();
$table->uuid('device_profile_xid');
$table->string('key_name');
$table->string('display_name');
$table->tinyInteger('display_on_dashboard')->default(0);
$table->tinyInteger('display_on_popup')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('timeseries_key_master');
}
};

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome Email</title>
</head>
<body>
<h1>Welcome, {{ $user['first_name'] }}!</h1>
<p>You have successfully registered with the following details:</p>
<ul>
<li><strong>Email:</strong> {{ $user['email'] }}</li>
<li><strong>Phone:</strong> {{ $user['phone'] }}</li>
</ul>
<p>
<a href="{{ $activationLink }}"
style="display: inline-block; padding: 10px 20px; color: #fff; background-color: #28a745; text-decoration: none; border-radius: 5px;">
Activate Account
</a>
</p>
<p>This link will expire in 24 hours.</p>
<p>If you did not create this account, please ignore this email.</p>
<p>Thank you for joining us!</p>
</body>
</html>

View File

@@ -31,3 +31,5 @@ Route::delete('/users-delete/{userId}', [UsersController::class, 'delete']);
//******************************************************* User API********************************************************
Route::post('/device/create-or-update', [DeviceController::class, 'createOrUpdateDevice'])->name('customer.create-or-update');
Route::post('/activate/{id}', [UsersController::class, 'activate'])->name('activate.user');
Route::post('/users-login', [UsersController::class, 'loginUser']);