u
This commit is contained in:
@@ -17,6 +17,7 @@ CORS_ORIGINS=http://localhost:5173
|
||||
# Auth — Google OAuth client ID and JWT signing secret
|
||||
GOOGLE_CLIENT_ID=
|
||||
JWT_SECRET=fallback_secret_please_change_in_production
|
||||
# Auto-create user on first login (when false, only allowlisted or invited emails can sign in / create an account)
|
||||
IMPLICIT_CREATE=false
|
||||
|
||||
# Database Provider — 'sqlite' or 'mssql' (defaults to 'mssql', or 'sqlite' if SQLITE_PATH is set)
|
||||
|
||||
@@ -4,7 +4,8 @@ Public. No cookie required.
|
||||
|
||||
Login with Google ID token
|
||||
|
||||
Verifies a Google ID token, checks allowlist (or creates entry when `IMPLICIT_CREATE=true`),
|
||||
Verifies a Google ID token, checks allowlist (or creates entry when `IMPLICIT_CREATE=true`
|
||||
or when the email has a pending auto-invitation),
|
||||
stores Google `sub` and profile image bytes, and sets an HTTP-only `token` cookie.
|
||||
`user.picture` is the profile image as base64 (same as GET /auth/me).
|
||||
|
||||
@@ -43,7 +44,7 @@ Login successful; `token` cookie set
|
||||
|--------|-------------|
|
||||
| 400 | Missing token or Google client not configured — `{"error":"…"}` |
|
||||
| 401 | Invalid Google token or account — `{"error":"…"}` |
|
||||
| 403 | Email not on allowlist — `{"error":"…"}` |
|
||||
| 403 | Email not on allowlist or invited — `{"error":"…"}` |
|
||||
| 500 | Server error — `{"error":"…"}` |
|
||||
|
||||
---
|
||||
|
||||
@@ -2,6 +2,7 @@ import jwt from 'jsonwebtoken';
|
||||
import { OAuth2Client } from 'google-auth-library';
|
||||
import env from '../../../config/env.js';
|
||||
import * as db from '../../../db/googleAuth.js';
|
||||
import * as autoinviteDb from '../../../db/autoinvite.js';
|
||||
import { clearCachedUser } from '../../middleware/auth.js';
|
||||
import { downloadPicture, toPictureBuffer } from '../../../util/pictureBinary.js';
|
||||
|
||||
@@ -20,7 +21,8 @@ export function register(app, basePath = '') {
|
||||
* tags: [Auth]
|
||||
* summary: Login with Google ID token
|
||||
* description: |
|
||||
* Verifies a Google ID token, checks allowlist (or creates entry when `IMPLICIT_CREATE=true`),
|
||||
* Verifies a Google ID token, checks allowlist (or creates entry when `IMPLICIT_CREATE=true`
|
||||
* or when the email has a pending auto-invitation),
|
||||
* stores Google `sub` and profile image bytes, and sets an HTTP-only `token` cookie.
|
||||
* `user.picture` is the profile image as base64 (same as GET /auth/me).
|
||||
* security: []
|
||||
@@ -64,7 +66,7 @@ export function register(app, basePath = '') {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
* 403:
|
||||
* description: Email not on allowlist
|
||||
* description: Email not on allowlist or invited
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
@@ -104,7 +106,7 @@ export function register(app, basePath = '') {
|
||||
}
|
||||
|
||||
let allowed = await db.getAllowedEmail(email);
|
||||
if (!allowed && env.implicitCreate) {
|
||||
if (!allowed && (env.implicitCreate || (await autoinviteDb.hasPendingInvite(email)))) {
|
||||
await db.addAllowedEmail(email);
|
||||
allowed = await db.getAllowedEmail(email);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getStore } from './store.js';
|
||||
import { getStore, getProvider } from './store.js';
|
||||
|
||||
export async function list(googleAuthId) {
|
||||
const store = await getStore();
|
||||
@@ -14,3 +14,14 @@ export async function remove(googleAuthId, id) {
|
||||
const store = await getStore();
|
||||
return store.autoinvite.remove(googleAuthId, id);
|
||||
}
|
||||
|
||||
export async function hasPendingInvite(email) {
|
||||
if (!email || typeof email !== 'string') return false;
|
||||
const normalized = email.trim().toLowerCase();
|
||||
const provider = await getProvider();
|
||||
const result = await provider.query(
|
||||
'SELECT 1 AS found FROM autoinvite WHERE email = @email',
|
||||
{ email: normalized }
|
||||
);
|
||||
return result.rows.length > 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user