This commit is contained in:
seb
2026-11-03 04:13:13 +01:00
parent 44e91a6973
commit 24563964a6
4 changed files with 53 additions and 2 deletions

View File

@@ -3,6 +3,7 @@ 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 * as companyDb from '../../../db/company.js';
import { clearCachedUser } from '../../middleware/auth.js';
import { downloadPicture, toPictureBuffer } from '../../../util/pictureBinary.js';
@@ -109,6 +110,13 @@ export function register(app, basePath = '') {
if (!allowed && (env.implicitCreate || (await autoinviteDb.hasPendingInvite(email)))) {
await db.addAllowedEmail(email);
allowed = await db.getAllowedEmail(email);
if (allowed && allowed.selectedCompanyId == null) {
const companies = await companyDb.listCompanies(allowed.id);
if (companies.length > 0) {
await db.setSelectedCompany(allowed.id, companies[0].id);
allowed = await db.getAllowedEmail(email);
}
}
}
if (!allowed) {
console.warn(`Login rejected: email not authorized (${email})`);

View File

@@ -2,6 +2,7 @@ import fs from 'fs';
import path from 'path';
import multer from 'multer';
import JSZip from 'jszip';
import env from '../../config/env.js';
import * as db from '../../db/company.js';
import * as googleAuth from '../../db/googleAuth.js';
import { clearCachedUser } from '../middleware/auth.js';
@@ -87,7 +88,7 @@ function companyErrorStatus(error) {
if (error.message === 'Company not found') return 404;
if (error.message === 'Company name not available') return 409;
if (error.message === 'Invalid tax rate' || error.message === 'Text required' || error.message === 'No company selected') return 400;
if (error.message === 'Not authorized') return 403;
if (error.message === 'Not authorized' || error.message === 'Invited users cannot create a company') return 403;
return 500;
}
@@ -186,6 +187,12 @@ export function register(app, basePath = '') {
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
* 403:
* description: Not authorized (invited users cannot create companies when implicit create is disabled)
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Error'
*/
// #region GET /company
@@ -209,6 +216,13 @@ export function register(app, basePath = '') {
return res.status(400).json({ error: body.error });
}
if (!env.implicitCreate) {
const isInvited = await db.isInvitedUser(req.user.id);
if (isInvited) {
return res.status(403).json({ error: 'Invited users cannot create a company' });
}
}
try {
const company = await db.createCompany(req.user.id, body);
await googleAuth.setSelectedCompany(req.user.id, company.id);

View File

@@ -1,4 +1,4 @@
import { getStore } from './store.js';
import { getStore, getProvider } from './store.js';
export async function listCompanies(authId) {
const store = await getStore();
@@ -34,3 +34,31 @@ export async function addCompanyHistory(googleAuthId, data) {
const store = await getStore();
return store.company.addHistory(googleAuthId, data);
}
export async function isInvitedUser(googleAuthId) {
const provider = await getProvider();
const isSqlite = provider?.dialect === 'sqlite3';
const sql = isSqlite
? `SELECT 1 AS is_creator
FROM companyuser cu
WHERE cu.google_auth_id = @googleAuthId
AND cu.id = (SELECT MIN(cu2.id) FROM companyuser cu2 WHERE cu2.company_id = cu.company_id)
LIMIT 1`
: `SELECT TOP 1 1 AS is_creator
FROM companyuser cu
WHERE cu.google_auth_id = @googleAuthId
AND cu.id = (SELECT MIN(cu2.id) FROM companyuser cu2 WHERE cu2.company_id = cu.company_id)`;
const creatorResult = await provider.query(sql, { googleAuthId });
if (creatorResult.rows.length > 0) {
return false;
}
const memberResult = await provider.query(
isSqlite
? `SELECT 1 AS is_member FROM companyuser WHERE google_auth_id = @googleAuthId LIMIT 1`
: `SELECT TOP 1 1 AS is_member FROM companyuser WHERE google_auth_id = @googleAuthId`,
{ googleAuthId }
);
return memberResult.rows.length > 0;
}