b912ff22bc
- SSO session auth gating on all protected pages - dashboard.php: account section (profile form + workspace panel), onboarding prompt modal, overview bar extracted to CSS classes, dashboard.css linked in page head - api/profile.php: save/dismiss endpoint for optional profile fields - assets/css/dashboard.css: account grid, dash-account-panel, dash-profile-form, profile-prompt-backdrop modal, overview bar classes, dash-section-kicker, dash-tier-badge base styles - includes/bootstrap.php: dbnToolsMainUserProfile, dbnToolsProfileNeedsPrompt, dbnToolsRequirePageAuth - scripts/sql/004_user_profile_fields.sql: nullable phone, address, and profile_prompt_dismissed_at columns Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
3.0 KiB
PHP
89 lines
3.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../includes/bootstrap.php';
|
|
|
|
dbnToolsRequireMethod('POST');
|
|
dbnToolsRequireAuth();
|
|
|
|
if (!dbnToolsIsFreeTier()) {
|
|
dbnToolsError('Main Do Better Norge account profile is available for SSO users.', 403, 'sso_required');
|
|
}
|
|
|
|
$userId = (int)($_SESSION['dbn_tools_sso_uid'] ?? 0);
|
|
if ($userId <= 0) {
|
|
dbnToolsError('Session user is missing.', 401, 'session_required');
|
|
}
|
|
|
|
$input = dbnToolsJsonInput(20000);
|
|
$currentProfile = dbnToolsMainUserProfile($userId) ?: [];
|
|
|
|
function profileString(array $input, string $key, int $maxChars, array $currentProfile): string
|
|
{
|
|
$raw = array_key_exists($key, $input) ? $input[$key] : ($currentProfile[$key] ?? '');
|
|
$value = trim((string)$raw);
|
|
if (mb_strlen($value, 'UTF-8') > $maxChars) {
|
|
dbnToolsError("Field {$key} is too long.", 422, 'field_too_long');
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
$displayName = profileString($input, 'display_name', 100, $currentProfile);
|
|
$phone = profileString($input, 'phone', 40, $currentProfile);
|
|
$addressLine1 = profileString($input, 'address_line1', 180, $currentProfile);
|
|
$addressLine2 = profileString($input, 'address_line2', 180, $currentProfile);
|
|
$postalCode = profileString($input, 'postal_code', 32, $currentProfile);
|
|
$city = profileString($input, 'city', 100, $currentProfile);
|
|
$addressRegion = profileString($input, 'address_region', 100, $currentProfile);
|
|
$country = strtoupper(profileString($input, 'country', 2, $currentProfile));
|
|
$preferredLanguage = dbnToolsNormalizeUiLanguage($input['preferred_language'] ?? ($_SESSION['lang'] ?? 'en'));
|
|
$dismissPrompt = !empty($input['dismiss_prompt']);
|
|
|
|
try {
|
|
$db = dbnmDb();
|
|
$stmt = $db->prepare(
|
|
'UPDATE users
|
|
SET display_name = NULLIF(?, ""),
|
|
phone = NULLIF(?, ""),
|
|
address_line1 = NULLIF(?, ""),
|
|
address_line2 = NULLIF(?, ""),
|
|
postal_code = NULLIF(?, ""),
|
|
city = NULLIF(?, ""),
|
|
address_region = NULLIF(?, ""),
|
|
country = NULLIF(?, ""),
|
|
preferred_language = ?,
|
|
profile_prompt_dismissed_at = CASE
|
|
WHEN ? = 1 THEN COALESCE(profile_prompt_dismissed_at, NOW())
|
|
ELSE profile_prompt_dismissed_at
|
|
END
|
|
WHERE id = ?'
|
|
);
|
|
$stmt->execute([
|
|
$displayName,
|
|
$phone,
|
|
$addressLine1,
|
|
$addressLine2,
|
|
$postalCode,
|
|
$city,
|
|
$addressRegion,
|
|
$country,
|
|
$preferredLanguage,
|
|
$dismissPrompt ? 1 : 0,
|
|
$userId,
|
|
]);
|
|
|
|
if ($displayName !== '') {
|
|
$_SESSION['dbn_tools_user_name'] = $displayName;
|
|
$_SESSION['dbn_tools_sso_name'] = $displayName;
|
|
}
|
|
$_SESSION['lang'] = $preferredLanguage;
|
|
|
|
dbnToolsRespond([
|
|
'ok' => true,
|
|
'profile' => dbnToolsMainUserProfile($userId),
|
|
]);
|
|
} catch (Throwable $e) {
|
|
error_log('[profile] ' . $e->getMessage());
|
|
dbnToolsError('Could not save profile details.', 500, 'profile_save_failed');
|
|
}
|