Merge pull request #3505 from eoussama/master

Added optional website ID for creation
This commit is contained in:
Mike Cao 2025-07-07 22:58:16 -07:00 committed by GitHub
commit b2a6e3f842
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 43 additions and 6 deletions

View file

@ -1,3 +1,5 @@
import { uuid } from '../../src/lib/crypto';
describe('Website API tests', () => {
Cypress.session.clearAllSavedSessions();
@ -65,6 +67,37 @@ describe('Website API tests', () => {
});
});
it('Creates a website with a fixed ID.', () => {
cy.fixture('websites').then(data => {
const websiteCreate = data.websiteCreate;
const fixedId = uuid();
cy.request({
method: 'POST',
url: '/api/websites',
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
body: { ...websiteCreate, id: fixedId },
}).then(response => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('id', fixedId);
expect(response.body).to.have.property('name', 'Cypress Website');
expect(response.body).to.have.property('domain', 'cypress.com');
// cleanup
cy.request({
method: 'DELETE',
url: `/api/websites/${fixedId}`,
headers: {
'Content-Type': 'application/json',
Authorization: Cypress.env('authorization'),
},
});
});
});
});
it('Returns all tracked websites.', () => {
cy.request({
method: 'GET',

View file

@ -122,7 +122,7 @@ CREATE TABLE umami.website_event_stats_hourly
min_time SimpleAggregateFunction(min, DateTime('UTC')),
max_time SimpleAggregateFunction(max, DateTime('UTC')),
tag SimpleAggregateFunction(groupArrayArray, Array(String)),
distinct_id,
distinct_id String,
created_at Datetime('UTC')
)
ENGINE = AggregatingMergeTree
@ -213,7 +213,7 @@ FROM (SELECT
min(created_at) min_time,
max(created_at) max_time,
arrayFilter(x -> x != '', groupArray(tag)) tag,
distinct_id String,
distinct_id,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,

View file

@ -16,7 +16,7 @@ const disableLogin = process.env.DISABLE_LOGIN;
const disableUI = process.env.DISABLE_UI;
const faviconURL = process.env.FAVICON_URL;
const forceSSL = process.env.FORCE_SSL;
const frameAncestors = process.env.ALLOWED_FRAME_URLS;
const frameAncestors = process.env.ALLOWED_FRAME_URLS ?? '';
const privateMode = process.env.PRIVATE_MODE;
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME;
const trackerScriptURL = process.env.TRACKER_SCRIPT_URL;

View file

@ -26,6 +26,7 @@ export async function POST(request: Request) {
domain: z.string().max(500),
shareId: z.string().max(50).nullable().optional(),
teamId: z.string().nullable().optional(),
id: z.string().uuid().nullable().optional(),
});
const { auth, body, error } = await parseRequest(request, schema);
@ -34,14 +35,14 @@ export async function POST(request: Request) {
return error();
}
const { name, domain, shareId, teamId } = body;
const { id, name, domain, shareId, teamId } = body;
if ((teamId && !(await canCreateTeamWebsite(auth, teamId))) || !(await canCreateWebsite(auth))) {
return unauthorized();
}
const data: any = {
id: uuid(),
id: id ?? uuid(),
createdBy: auth.user.id,
name,
domain,

View file

@ -130,7 +130,9 @@ export async function getLocation(ip: string = '', headers: Headers, hasPayloadI
);
}
const result = global[MAXMIND].get(ip);
// When the client IP is extracted from headers, sometimes the value includes a port
const cleanIp = ip?.split(':')[0];
const result = global[MAXMIND].get(cleanIp);
if (result) {
const country = result.country?.iso_code ?? result?.registered_country?.iso_code;

View file

@ -150,6 +150,7 @@
try {
const res = await fetch(endpoint, {
keepalive: true,
method: 'POST',
body: JSON.stringify({ type, payload }),
headers: {