mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-04-15 09:14:08 +00:00
Existing accounts inherited the company language at creation time and there was no way to change UI language per user. Add a 'Default (Company Language)' entry to the language selector in UserGeneralView, persist the choice through userStore.updateUserSettings and reload the i18n bundle via window.loadLanguage. The 'default' sentinel keeps the user opted in to the company-wide setting. Bootstrap (global.store) now syncs userForm from current_user data and resolves the active UI language as user > company > 'en'. RegisterController, InvitationRegistrationController and MemberService seed new users with language=default instead of copying the current company setting, so promoting/inviting members no longer leaks the inviter's frozen language.
86 lines
2.5 KiB
PHP
86 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Company\Auth;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\CompanyInvitation;
|
|
use App\Models\User;
|
|
use App\Services\InvitationService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class InvitationRegistrationController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly InvitationService $invitationService,
|
|
) {}
|
|
|
|
/**
|
|
* Get invitation details by token (public endpoint for registration page).
|
|
*/
|
|
public function details(string $token): JsonResponse
|
|
{
|
|
$invitation = CompanyInvitation::where('token', $token)
|
|
->pending()
|
|
->with(['company', 'role'])
|
|
->first();
|
|
|
|
if (! $invitation) {
|
|
return response()->json([
|
|
'error' => 'Invitation not found or expired.',
|
|
], 404);
|
|
}
|
|
|
|
return response()->json([
|
|
'email' => $invitation->email,
|
|
'company_name' => $invitation->company->name,
|
|
'role_name' => $invitation->role->title,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Register a new user and auto-accept the invitation.
|
|
*/
|
|
public function register(Request $request): JsonResponse
|
|
{
|
|
$request->validate([
|
|
'name' => 'required|string|max:255',
|
|
'email' => 'required|string|email|max:255|unique:users',
|
|
'password' => 'required|string|min:8|confirmed',
|
|
'invitation_token' => 'required|string',
|
|
]);
|
|
|
|
$invitation = CompanyInvitation::where('token', $request->invitation_token)
|
|
->pending()
|
|
->first();
|
|
|
|
if (! $invitation) {
|
|
throw ValidationException::withMessages([
|
|
'invitation_token' => ['Invitation not found or expired.'],
|
|
]);
|
|
}
|
|
|
|
if ($invitation->email !== $request->email) {
|
|
throw ValidationException::withMessages([
|
|
'email' => ['Email does not match the invitation.'],
|
|
]);
|
|
}
|
|
|
|
$user = User::create([
|
|
'name' => $request->name,
|
|
'email' => $request->email,
|
|
'password' => $request->password,
|
|
]);
|
|
|
|
$user->setSettings(['language' => 'default']);
|
|
|
|
$this->invitationService->accept($invitation, $user);
|
|
|
|
return response()->json([
|
|
'type' => 'Bearer',
|
|
'token' => $user->createToken('web')->plainTextToken,
|
|
]);
|
|
}
|
|
}
|