u
This commit is contained in:
@@ -60,6 +60,7 @@ Created; selected company updated
|
|||||||
|--------|-------------|
|
|--------|-------------|
|
||||||
| 400 | Validation error — `{"error":"…"}` |
|
| 400 | Validation error — `{"error":"…"}` |
|
||||||
| 401 | Unauthorized — `{"error":"…"}` |
|
| 401 | Unauthorized — `{"error":"…"}` |
|
||||||
|
| 403 | Not authorized (invited users cannot create companies when implicit create is disabled) — `{"error":"…"}` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { OAuth2Client } from 'google-auth-library';
|
|||||||
import env from '../../../config/env.js';
|
import env from '../../../config/env.js';
|
||||||
import * as db from '../../../db/googleAuth.js';
|
import * as db from '../../../db/googleAuth.js';
|
||||||
import * as autoinviteDb from '../../../db/autoinvite.js';
|
import * as autoinviteDb from '../../../db/autoinvite.js';
|
||||||
|
import * as companyDb from '../../../db/company.js';
|
||||||
import { clearCachedUser } from '../../middleware/auth.js';
|
import { clearCachedUser } from '../../middleware/auth.js';
|
||||||
import { downloadPicture, toPictureBuffer } from '../../../util/pictureBinary.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)))) {
|
if (!allowed && (env.implicitCreate || (await autoinviteDb.hasPendingInvite(email)))) {
|
||||||
await db.addAllowedEmail(email);
|
await db.addAllowedEmail(email);
|
||||||
allowed = await db.getAllowedEmail(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) {
|
if (!allowed) {
|
||||||
console.warn(`Login rejected: email not authorized (${email})`);
|
console.warn(`Login rejected: email not authorized (${email})`);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import fs from 'fs';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import multer from 'multer';
|
import multer from 'multer';
|
||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
|
import env from '../../config/env.js';
|
||||||
import * as db from '../../db/company.js';
|
import * as db from '../../db/company.js';
|
||||||
import * as googleAuth from '../../db/googleAuth.js';
|
import * as googleAuth from '../../db/googleAuth.js';
|
||||||
import { clearCachedUser } from '../middleware/auth.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 not found') return 404;
|
||||||
if (error.message === 'Company name not available') return 409;
|
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 === '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;
|
return 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,6 +187,12 @@ export function register(app, basePath = '') {
|
|||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: '#/components/schemas/Error'
|
* $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
|
// #region GET /company
|
||||||
|
|
||||||
@@ -209,6 +216,13 @@ export function register(app, basePath = '') {
|
|||||||
return res.status(400).json({ error: body.error });
|
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 {
|
try {
|
||||||
const company = await db.createCompany(req.user.id, body);
|
const company = await db.createCompany(req.user.id, body);
|
||||||
await googleAuth.setSelectedCompany(req.user.id, company.id);
|
await googleAuth.setSelectedCompany(req.user.id, company.id);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getStore } from './store.js';
|
import { getStore, getProvider } from './store.js';
|
||||||
|
|
||||||
export async function listCompanies(authId) {
|
export async function listCompanies(authId) {
|
||||||
const store = await getStore();
|
const store = await getStore();
|
||||||
@@ -34,3 +34,31 @@ export async function addCompanyHistory(googleAuthId, data) {
|
|||||||
const store = await getStore();
|
const store = await getStore();
|
||||||
return store.company.addHistory(googleAuthId, data);
|
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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user