feat: native OAuth login page, architecture docs, docs site update
- Add GET/POST /login to hermes for first-party cookie during OAuth popup (fixes browser CHIPS cookie partitioning that broke claude.ai connection) - Add role column to all findCustomer* SQL queries in src/auth.ts - Add claude.ai tab to docs/getting-started.html with OAuth flow steps - Add ARCHITECTURE.md with system diagrams, data flow, and key invariants - Rewrite README.md and DEPLOY.md to reflect actual MicroK8s deployment - Deploy updated docs site (squaremcp-docs sha256 updated) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ export interface JWTPayload {
|
||||
sub: string; // customer id
|
||||
email: string;
|
||||
plan: string;
|
||||
role?: string;
|
||||
}
|
||||
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
@@ -37,11 +38,12 @@ interface CustomerRow extends RowDataPacket {
|
||||
active: boolean;
|
||||
api_key: string;
|
||||
password_hash: string | null;
|
||||
role: string;
|
||||
}
|
||||
|
||||
export async function findCustomerByEmail(email: string): Promise<CustomerRow | null> {
|
||||
const [rows] = await getPool().query<CustomerRow[]>(
|
||||
'SELECT id, email, plan, active, api_key, password_hash FROM customers WHERE email = ?',
|
||||
'SELECT id, email, plan, active, api_key, password_hash, role FROM customers WHERE email = ?',
|
||||
[email]
|
||||
);
|
||||
return rows[0] ?? null;
|
||||
@@ -49,7 +51,7 @@ export async function findCustomerByEmail(email: string): Promise<CustomerRow |
|
||||
|
||||
export async function findCustomerById(id: string): Promise<CustomerRow | null> {
|
||||
const [rows] = await getPool().query<CustomerRow[]>(
|
||||
'SELECT id, email, plan, active, api_key, password_hash FROM customers WHERE id = ?',
|
||||
'SELECT id, email, plan, active, api_key, password_hash, role FROM customers WHERE id = ?',
|
||||
[id]
|
||||
);
|
||||
return rows[0] ?? null;
|
||||
@@ -77,7 +79,7 @@ export async function setResetToken(email: string, token: string): Promise<boole
|
||||
|
||||
export async function findCustomerByResetToken(token: string) {
|
||||
const [rows] = await getPool().query<CustomerRow[]>(
|
||||
'SELECT id, email, plan, active, api_key, password_hash FROM customers WHERE reset_token = ? AND reset_expires_at > NOW()',
|
||||
'SELECT id, email, plan, active, api_key, password_hash, role FROM customers WHERE reset_token = ? AND reset_expires_at > NOW()',
|
||||
[token]
|
||||
);
|
||||
return rows[0] ?? null;
|
||||
|
||||
Reference in New Issue
Block a user