Migrate to Postgresql for better network handling. Add more user functionality.

This commit is contained in:
Dan Milne
2025-11-06 14:08:39 +11:00
parent 85252a1a07
commit fc567f0b91
69 changed files with 4266 additions and 952 deletions

View File

@@ -1,21 +1,91 @@
<div class="mx-auto md:w-2/3 w-full">
<% if alert = flash[:alert] %>
<p class="py-2 px-3 bg-red-50 mb-5 text-red-500 font-medium rounded-lg inline-block" id="alert"><%= alert %></p>
<% end %>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<% if alert = flash[:alert] %>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<%= alert %>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<% end %>
<h1 class="font-bold text-4xl">Update your password</h1>
<div class="card">
<div class="card-header">
<h3 class="card-title mb-0">Account Settings</h3>
</div>
<div class="card-body">
<!-- User Info -->
<div class="mb-4">
<h5>Profile Information</h5>
<table class="table table-sm">
<tr>
<th>Email:</th>
<td><%= @user.email_address %></td>
</tr>
<tr>
<th>Role:</th>
<td><span class="badge bg-<%= @user.admin? ? 'danger' : @user.viewer? ? 'info' : 'primary' %>"><%= @user.role %></span></td>
</tr>
<tr>
<th>Authentication:</th>
<td>
<% if @user.password_digest.present? %>
<span class="badge bg-success">Local Password</span>
<% else %>
<span class="badge bg-info">OIDC</span>
<% end %>
</td>
</tr>
<tr>
<th>Active Sessions:</th>
<td><%= @user.sessions.count %></td>
</tr>
<tr>
<th>Member Since:</th>
<td><%= @user.created_at.strftime('%B %d, %Y') %></td>
</tr>
</table>
</div>
<%= form_with url: password_path(params[:token]), method: :put, class: "contents" do |form| %>
<div class="my-5">
<%= form.password_field :password, required: true, autocomplete: "new-password", placeholder: "Enter new password", maxlength: 72, class: "block shadow-sm rounded-md border border-gray-400 focus:outline-solid focus:outline-blue-600 px-3 py-2 mt-2 w-full" %>
<% if @user.password_digest.present? %>
<!-- Password Change Form -->
<div class="border-top pt-4">
<h5>Change Password</h5>
<p class="text-muted">Changing your password will log you out of all other devices.</p>
<%= form_with model: @user, url: password_path, method: :patch, class: "row g-3" do |form| %>
<div class="col-md-6">
<%= form.label :current_password, "Current Password", class: "form-label" %>
<%= form.password_field :current_password, required: true, autocomplete: "current-password", class: "form-control" %>
</div>
<div class="col-md-6">
<%= form.label :password, "New Password", class: "form-label" %>
<%= form.password_field :password, required: true, autocomplete: "new-password", minlength: 8, class: "form-control" %>
<div class="form-text">Minimum 8 characters</div>
</div>
<div class="col-md-6">
<%= form.label :password_confirmation, "Confirm New Password", class: "form-label" %>
<%= form.password_field :password_confirmation, required: true, autocomplete: "new-password", minlength: 8, class: "form-control" %>
</div>
<div class="col-12">
<%= form.submit "Update Password", class: "btn btn-primary" %>
<%= link_to "Cancel", root_path, class: "btn btn-secondary ms-2" %>
</div>
<% end %>
</div>
<% else %>
<!-- OIDC User Info -->
<div class="border-top pt-4">
<div class="alert alert-info">
<h6>🔐 OIDC Authentication</h6>
<p class="mb-0">Your account is managed through your OIDC provider. To change your password, please use your provider's account management tools.</p>
</div>
</div>
<% end %>
</div>
</div>
</div>
<div class="my-5">
<%= form.password_field :password_confirmation, required: true, autocomplete: "new-password", placeholder: "Repeat new password", maxlength: 72, class: "block shadow-sm rounded-md border border-gray-400 focus:outline-solid focus:outline-blue-600 px-3 py-2 mt-2 w-full" %>
</div>
<div class="inline">
<%= form.submit "Save", class: "w-full sm:w-auto text-center rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white inline-block font-medium cursor-pointer" %>
</div>
<% end %>
</div>
</div>

View File

@@ -1,17 +0,0 @@
<div class="mx-auto md:w-2/3 w-full">
<% if alert = flash[:alert] %>
<p class="py-2 px-3 bg-red-50 mb-5 text-red-500 font-medium rounded-lg inline-block" id="alert"><%= alert %></p>
<% end %>
<h1 class="font-bold text-4xl">Forgot your password?</h1>
<%= form_with url: passwords_path, class: "contents" do |form| %>
<div class="my-5">
<%= form.email_field :email_address, required: true, autofocus: true, autocomplete: "username", placeholder: "Enter your email address", value: params[:email_address], class: "block shadow-sm rounded-md border border-gray-400 focus:outline-solid focus:outline-blue-600 px-3 py-2 mt-2 w-full" %>
</div>
<div class="inline">
<%= form.submit "Email reset instructions", class: "w-full sm:w-auto text-center rounded-lg px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white inline-block font-medium cursor-pointer" %>
</div>
<% end %>
</div>