- By continuing you are indicating that you accept
+ By continuing you are accepting
our
Terms of Service and
diff --git a/dashboard/server/api/integrations/github/oauth2/callback.ts b/dashboard/server/api/integrations/github/oauth2/callback.ts
new file mode 100644
index 0000000..fdb5eea
--- /dev/null
+++ b/dashboard/server/api/integrations/github/oauth2/callback.ts
@@ -0,0 +1,72 @@
+
+import { createUserJwt } from '~/server/AuthManager';
+import { UserModel } from '@schema/UserSchema';
+import EmailService from '@services/EmailService';
+
+const config = useRuntimeConfig();
+
+export default defineEventHandler(async event => {
+
+ const { code } = getQuery(event);
+ console.log('CODE', code);
+
+ const redirect_uri = 'http://127.0.0.1:3000'
+
+ const res = await fetch(`https://github.com/login/oauth/access_token?client_id=${config.GITHUB_AUTH_CLIENT_ID}&client_secret=${config.GITHUB_AUTH_CLIENT_SECRET}&code=${code}&redirect_url=${redirect_uri}`, {
+ headers: {
+ "Accept": "application/json",
+ "Accept-Encoding": "application/json",
+ },
+ });
+
+ const data = await res.json();
+
+ const access_token = data.access_token;
+
+ console.log(data);
+
+ return sendRedirect(event,`http://127.0.0.1:3000/login?github_access_token=${access_token}`)
+
+
+ // const origin = event.headers.get('origin');
+
+ // const tokenResponse = await client.getToken({
+ // code: body.code,
+ // redirect_uri: origin || ''
+ // });
+
+ // const tokens = tokenResponse.tokens;
+
+ // const ticket = await client.verifyIdToken({
+ // idToken: tokens.id_token || '',
+ // audience: GOOGLE_AUTH_CLIENT_ID,
+ // });
+
+ // const payload = ticket.getPayload();
+ // if (!payload) return { error: true, access_token: '' };
+
+
+ // const user = await UserModel.findOne({ email: payload.email });
+
+ // if (user) return { error: false, access_token: createUserJwt({ email: user.email, name: user.name }) }
+
+
+ // const newUser = new UserModel({
+ // email: payload.email,
+ // given_name: payload.given_name,
+ // name: payload.name,
+ // locale: payload.locale,
+ // picture: payload.picture,
+ // created_at: Date.now()
+ // });
+
+ // const savedUser = await newUser.save();
+
+ // setImmediate(() => {
+ // console.log('SENDING WELCOME EMAIL TO', payload.email);
+ // if (payload.email) EmailService.sendWelcomeEmail(payload.email);
+ // });
+
+ // return { error: false, access_token: createUserJwt({ email: savedUser.email, name: savedUser.name }) }
+
+});
\ No newline at end of file
diff --git a/dashboard/server/api/metrics/[project_id]/timeline/events.post.ts b/dashboard/server/api/metrics/[project_id]/timeline/events.post.ts
index 36ed24d..9e02eb8 100644
--- a/dashboard/server/api/metrics/[project_id]/timeline/events.post.ts
+++ b/dashboard/server/api/metrics/[project_id]/timeline/events.post.ts
@@ -2,7 +2,7 @@ import { EventModel } from "@schema/metrics/EventSchema";
import { getTimeline } from "./generic";
import { Redis, TIMELINE_EXPIRE_TIME } from "~/server/services/CacheService";
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
-import { executeTimelineAggregation, fillAndMergeTimelineAggregation } from "~/server/services/TimelineService";
+import { executeTimelineAggregation, fillAndMergeTimelineAggregation, fillAndMergeTimelineAggregationV2 } from "~/server/services/TimelineService";
export default defineEventHandler(async event => {
const project_id = getRequestProjectId(event);
@@ -27,7 +27,7 @@ export default defineEventHandler(async event => {
model: EventModel,
from, to, slice
});
- const timelineFilledMerged = fillAndMergeTimelineAggregation(timelineData, slice);
+ const timelineFilledMerged = fillAndMergeTimelineAggregationV2(timelineData, slice, from, to);
return timelineFilledMerged;
});
diff --git a/dashboard/server/api/metrics/[project_id]/timeline/referrers.post.ts b/dashboard/server/api/metrics/[project_id]/timeline/referrers.post.ts
index 813ef6e..b53581c 100644
--- a/dashboard/server/api/metrics/[project_id]/timeline/referrers.post.ts
+++ b/dashboard/server/api/metrics/[project_id]/timeline/referrers.post.ts
@@ -1,9 +1,7 @@
-import { getTimeline } from "./generic";
import { VisitModel } from "@schema/metrics/VisitSchema";
-import DateService from "@services/DateService";
import { Redis, TIMELINE_EXPIRE_TIME } from "~/server/services/CacheService";
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
-import { executeAdvancedTimelineAggregation, fillAndMergeTimelineAggregation } from "~/server/services/TimelineService";
+import { executeAdvancedTimelineAggregation, fillAndMergeTimelineAggregationV2 } from "~/server/services/TimelineService";
export default defineEventHandler(async event => {
const project_id = getRequestProjectId(event);
@@ -31,7 +29,7 @@ export default defineEventHandler(async event => {
referrer
}
});
- const timelineFilledMerged = fillAndMergeTimelineAggregation(timelineData, slice);
+ const timelineFilledMerged = fillAndMergeTimelineAggregationV2(timelineData, slice, from, to);
return timelineFilledMerged;
});
diff --git a/dashboard/server/api/metrics/[project_id]/timeline/sessions.post.ts b/dashboard/server/api/metrics/[project_id]/timeline/sessions.post.ts
index 3a776a7..9cd9cc7 100644
--- a/dashboard/server/api/metrics/[project_id]/timeline/sessions.post.ts
+++ b/dashboard/server/api/metrics/[project_id]/timeline/sessions.post.ts
@@ -2,7 +2,7 @@ import { getTimeline } from "./generic";
import { Redis, TIMELINE_EXPIRE_TIME } from "~/server/services/CacheService";
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
import { SessionModel } from "@schema/metrics/SessionSchema";
-import { executeTimelineAggregation, fillAndMergeTimelineAggregation } from "~/server/services/TimelineService";
+import { executeTimelineAggregation, fillAndMergeTimelineAggregationV2 } from "~/server/services/TimelineService";
export default defineEventHandler(async event => {
const project_id = getRequestProjectId(event);
@@ -28,7 +28,7 @@ export default defineEventHandler(async event => {
model: SessionModel,
from, to, slice
});
- const timelineFilledMerged = fillAndMergeTimelineAggregation(timelineData, slice);
+ const timelineFilledMerged = fillAndMergeTimelineAggregationV2(timelineData, slice, from, to);
return timelineFilledMerged;
});
diff --git a/dashboard/server/api/metrics/[project_id]/timeline/sessions_duration.post.ts b/dashboard/server/api/metrics/[project_id]/timeline/sessions_duration.post.ts
index 46b44fe..4848a20 100644
--- a/dashboard/server/api/metrics/[project_id]/timeline/sessions_duration.post.ts
+++ b/dashboard/server/api/metrics/[project_id]/timeline/sessions_duration.post.ts
@@ -2,7 +2,7 @@ import { getTimeline } from "./generic";
import { Redis, TIMELINE_EXPIRE_TIME } from "~/server/services/CacheService";
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
import { SessionModel } from "@schema/metrics/SessionSchema";
-import { executeAdvancedTimelineAggregation, executeTimelineAggregation, fillAndMergeTimelineAggregation } from "~/server/services/TimelineService";
+import { executeAdvancedTimelineAggregation, fillAndMergeTimelineAggregationV2 } from "~/server/services/TimelineService";
export default defineEventHandler(async event => {
const project_id = getRequestProjectId(event);
@@ -45,7 +45,7 @@ export default defineEventHandler(async event => {
count: { $divide: ["$duration", "$count"] }
},
});
- const timelineFilledMerged = fillAndMergeTimelineAggregation(timelineData, slice);
+ const timelineFilledMerged = fillAndMergeTimelineAggregationV2(timelineData, slice, from ,to);
return timelineFilledMerged;
});
diff --git a/dashboard/server/api/metrics/[project_id]/timeline/visits.post.ts b/dashboard/server/api/metrics/[project_id]/timeline/visits.post.ts
index 145cec1..1a4696c 100644
--- a/dashboard/server/api/metrics/[project_id]/timeline/visits.post.ts
+++ b/dashboard/server/api/metrics/[project_id]/timeline/visits.post.ts
@@ -2,7 +2,7 @@ import { VisitModel } from "@schema/metrics/VisitSchema";
import { Redis, TIMELINE_EXPIRE_TIME } from "~/server/services/CacheService";
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
import DateService from "@services/DateService";
-import { executeTimelineAggregation, fillAndMergeTimelineAggregation } from "~/server/services/TimelineService";
+import { executeTimelineAggregation, fillAndMergeTimelineAggregationV2 } from "~/server/services/TimelineService";
export default defineEventHandler(async event => {
const project_id = getRequestProjectId(event);
@@ -28,11 +28,9 @@ export default defineEventHandler(async event => {
model: VisitModel,
from, to, slice,
});
- const timelineFilledMerged = fillAndMergeTimelineAggregation(timelineData, slice);
+ const timelineFilledMerged = fillAndMergeTimelineAggregationV2(timelineData, slice, from, to);
return timelineFilledMerged;
});
-
-
});
\ No newline at end of file
diff --git a/dashboard/server/services/TimelineService.ts b/dashboard/server/services/TimelineService.ts
index 88c6e1c..16da83d 100644
--- a/dashboard/server/services/TimelineService.ts
+++ b/dashboard/server/services/TimelineService.ts
@@ -61,4 +61,10 @@ export function fillAndMergeTimelineAggregation(timeline: { _id: string, count:
const filledDates = DateService.fillDates(timeline.map(e => e._id), slice);
const merged = DateService.mergeFilledDates(filledDates, timeline, '_id', slice, { count: 0 });
return merged;
+}
+
+export function fillAndMergeTimelineAggregationV2(timeline: { _id: string, count: number }[], slice: Slice, from: string, to: string) {
+ const filledDates = DateService.createBetweenDates(from, to, slice);
+ const merged = DateService.mergeFilledDates(filledDates.dates, timeline, '_id', slice, { count: 0 });
+ return merged;
}
\ No newline at end of file
diff --git a/shared/services/DateService.ts b/shared/services/DateService.ts
index 44f3537..ee86cdd 100644
--- a/shared/services/DateService.ts
+++ b/shared/services/DateService.ts
@@ -102,6 +102,18 @@ class DateService {
}
}
+ createBetweenDates(from: string, to: string, slice: Slice) {
+ let start = dayjs(from);
+ const end = dayjs(to);
+ const filledDates: dayjs.Dayjs[] = [];
+ while (start.isBefore(end) || start.isSame(end)) {
+ filledDates.push(start);
+ start = start.add(1, slice);
+ }
+ return { dates: filledDates, from, to };
+ }
+
+
fillDates(dates: string[], slice: Slice) {
const allDates: dayjs.Dayjs[] = [];
const firstDate = dayjs(dates.at(0));
@@ -109,7 +121,7 @@ class DateService {
let currentDate = firstDate.clone();
allDates.push(currentDate);
-
+
while (currentDate.isBefore(lastDate, slice)) {
currentDate = currentDate.add(1, slice);
allDates.push(currentDate);
@@ -121,7 +133,7 @@ class DateService {
mergeFilledDates
, K extends keyof T>(dates: dayjs.Dayjs[], items: T[], dateField: K, slice: Slice, fillData: Omit) {
const result = new Array();
for (const date of dates) {
- const item = items.find(e => dayjs(e[dateField]).isSame(date), slice);
+ const item = items.find(e => dayjs(e[dateField]).isSame(date, slice));
result.push(item ?? { ...fillData, [dateField]: date.format() } as T);
}
return result;