NeahNew/.next/server/chunks/1890.js
2025-05-06 23:01:34 +02:00

1 line
16 KiB
JavaScript

exports.id=1890,exports.ids=[1890],exports.modules={12269:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},19854:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o={};Object.defineProperty(t,"default",{enumerable:!0,get:function(){return n.default}});var a=r(12269);Object.keys(a).forEach(function(e){!("default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(o,e))&&(e in t&&t[e]===a[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}}))});var n=function(e,t){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=i(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},a=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var n in e)if("default"!==n&&({}).hasOwnProperty.call(e,n)){var s=a?Object.getOwnPropertyDescriptor(e,n):null;s&&(s.get||s.set)?Object.defineProperty(o,n,s):o[n]=e[n]}return o.default=e,r&&r.set(e,o),o}(r(35426));function i(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(i=function(e){return e?r:t})(e)}Object.keys(n).forEach(function(e){!("default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(o,e))&&(e in t&&t[e]===n[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return n[e]}}))})},26690:(e,t,r)=>{"use strict";r.d(t,{N:()=>s});var o=r(1926),a=r(10591);function n(e){let t=process.env[e];if(!t)throw Error(`Missing required environment variable: ${e}`);return t}async function i(e){try{let t=await fetch(`${process.env.KEYCLOAK_ISSUER}/protocol/openid-connect/token`,{headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:process.env.KEYCLOAK_CLIENT_ID,client_secret:process.env.KEYCLOAK_CLIENT_SECRET,grant_type:"refresh_token",refresh_token:e.refreshToken||""}),method:"POST"}),r=await t.json();if(!t.ok)throw r;return{...e,accessToken:r.access_token,refreshToken:r.refresh_token??e.refreshToken,accessTokenExpires:Date.now()+1e3*r.expires_in}}catch(t){return console.error("Error refreshing access token:",t),{...e,error:"RefreshAccessTokenError"}}}let s={providers:[(0,o.A)({clientId:n("KEYCLOAK_CLIENT_ID"),clientSecret:n("KEYCLOAK_CLIENT_SECRET"),issuer:n("KEYCLOAK_ISSUER"),authorization:{params:{scope:"openid profile email roles"}},profile(e){console.log("Keycloak profile callback:",{rawProfile:e,rawRoles:e.roles,realmAccess:e.realm_access,groups:e.groups});let t=e.realm_access?.roles||[];console.log("Profile callback raw roles:",t);let r=t.map(e=>e.replace(/^ROLE_/,"").toLowerCase());return console.log("Profile callback cleaned roles:",r),{id:e.sub,name:e.name??e.preferred_username,email:e.email,first_name:e.given_name??"",last_name:e.family_name??"",username:e.preferred_username??e.email?.split("@")[0]??"",role:r}}})],session:{strategy:"jwt",maxAge:2592e3},callbacks:{async jwt({token:e,account:t,profile:r}){if(t&&r){let o=(r.realm_access?.roles||[]).map(e=>e.replace(/^ROLE_/,"").toLowerCase());e.accessToken=t.access_token??"",e.refreshToken=t.refresh_token??"",e.accessTokenExpires=t.expires_at??0,e.sub=r.sub,e.role=o,e.username=r.preferred_username??"",e.first_name=r.given_name??"",e.last_name=r.family_name??""}else if(e.accessToken)try{let t=(0,a.s)(e.accessToken);t.realm_access?.roles&&(e.role=t.realm_access.roles.map(e=>e.replace(/^ROLE_/,"").toLowerCase()))}catch(e){console.error("Error decoding token:",e)}return Date.now()<1e3*e.accessTokenExpires?e:i(e)},async session({session:e,token:t}){if(t.error)throw Error(t.error);let r=Array.isArray(t.role)?t.role:[];return e.user={id:t.sub??"",email:t.email??null,name:t.name??null,image:null,username:t.username??"",first_name:t.first_name??"",last_name:t.last_name??"",role:r,nextcloudInitialized:!1},e.accessToken=t.accessToken,e}},pages:{signIn:"/signin",error:"/signin"},debug:!1}},70014:(e,t,r)=>{"use strict";r.d(t,{J:()=>s});var o=r(19854),a=r(26690);class n{constructor(){this.sourceName="leantime",this.apiUrl=process.env.LEANTIME_API_URL||"",this.apiToken=process.env.LEANTIME_TOKEN||"",console.log("[LEANTIME_ADAPTER] Initialized with API URL and token")}async getNotifications(e,t=1,r=20){console.log(`[LEANTIME_ADAPTER] getNotifications called for userId: ${e}, page: ${t}, limit: ${r}`);try{let o=await this.getUserEmail();if(console.log("[LEANTIME_ADAPTER] Retrieved email from session:",o||"null"),!o)return console.error("[LEANTIME_ADAPTER] Could not get user email from session"),[];let a=await this.getLeantimeUserId(o);if(console.log(`[LEANTIME_ADAPTER] Retrieved Leantime userId for email ${o}:`,a||"null"),!a)return console.error("[LEANTIME_ADAPTER] User not found in Leantime:",o),[];console.log("[LEANTIME_ADAPTER] Sending request to get all notifications");let n={jsonrpc:"2.0",method:"leantime.rpc.Notifications.Notifications.getAllNotifications",params:{userId:a,showNewOnly:0,limitStart:(t-1)*r,limitEnd:r,filterOptions:[]},id:1};console.log("[LEANTIME_ADAPTER] Request body:",JSON.stringify(n));let i=await fetch(`${this.apiUrl}/api/jsonrpc`,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.apiToken},body:JSON.stringify(n)});if(console.log("[LEANTIME_ADAPTER] Response status:",i.status),!i.ok){let e=await i.text();return console.error("[LEANTIME_ADAPTER] Failed to fetch Leantime notifications:",{status:i.status,body:e.substring(0,200)+(e.length>200?"...":"")}),[]}let s=await i.text();console.log("[LEANTIME_ADAPTER] Raw response (truncated):",s.substring(0,200)+(s.length>200?"...":""));let l=JSON.parse(s);if(console.log("[LEANTIME_ADAPTER] Parsed response data:",{hasResult:!!l.result,resultIsArray:Array.isArray(l.result),resultLength:Array.isArray(l.result)?l.result.length:"n/a",error:l.error}),!l.result||!Array.isArray(l.result))return l.error?console.error(`[LEANTIME_ADAPTER] API error: ${l.error.message||JSON.stringify(l.error)}`):console.error("[LEANTIME_ADAPTER] Invalid response format from Leantime notifications API"),[];let c=this.transformNotifications(l.result,e);return console.log("[LEANTIME_ADAPTER] Transformed notifications count:",c.length),c}catch(e){return console.error("[LEANTIME_ADAPTER] Error fetching Leantime notifications:",e),[]}}async getNotificationCount(e){console.log(`[LEANTIME_ADAPTER] getNotificationCount called for userId: ${e}`);try{let t=await this.getNotifications(e,1,100),r=t.length,o=t.filter(e=>!e.isRead).length;return console.log("[LEANTIME_ADAPTER] Notification counts:",{total:r,unread:o}),{total:r,unread:o,sources:{leantime:{total:r,unread:o}}}}catch(e){return console.error("[LEANTIME_ADAPTER] Error fetching notification count:",e),{total:0,unread:0,sources:{leantime:{total:0,unread:0}}}}}async markAsRead(e,t){console.log(`[LEANTIME_ADAPTER] markAsRead called for ${t}`);try{let e=t.replace(`${this.sourceName}-`,""),r=await this.getUserEmail();if(!r)return console.error("[LEANTIME_ADAPTER] Could not get user email from session"),!1;let o=await this.getLeantimeUserId(r);if(!o)return console.error("[LEANTIME_ADAPTER] User not found in Leantime:",r),!1;let a={jsonrpc:"2.0",method:"leantime.rpc.Notifications.Notifications.markNotificationAsRead",params:{userId:o,notificationId:parseInt(e)},id:1},n=await fetch(`${this.apiUrl}/api/jsonrpc`,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.apiToken},body:JSON.stringify(a)});if(!n.ok)return console.error(`[LEANTIME_ADAPTER] Failed to mark notification as read: ${n.status}`),!1;let i=await n.json();return!0===i.result||"true"===i.result||!!i.result}catch(e){return console.error("[LEANTIME_ADAPTER] Error marking notification as read:",e),!1}}async markAllAsRead(e){console.log(`[LEANTIME_ADAPTER] markAllAsRead called for ${e}`);try{let e=await this.getUserEmail();if(!e)return console.error("[LEANTIME_ADAPTER] Could not get user email from session"),!1;let t=await this.getLeantimeUserId(e);if(!t)return console.error("[LEANTIME_ADAPTER] User not found in Leantime:",e),!1;let r=await fetch(`${this.apiUrl}/api/jsonrpc`,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.apiToken},body:JSON.stringify({jsonrpc:"2.0",method:"leantime.rpc.Notifications.Notifications.markAllNotificationsAsRead",params:{userId:t},id:1})});if(!r.ok)return console.error(`[LEANTIME_ADAPTER] Failed to mark all notifications as read: ${r.status}`),!1;let o=await r.json();return!0===o.result||"true"===o.result||!!o.result}catch(e){return console.error("[LEANTIME_ADAPTER] Error marking all notifications as read:",e),!1}}async isConfigured(){return!!(this.apiUrl&&this.apiToken)}transformNotifications(e,t){return Array.isArray(e)?e.map(e=>{let r=e.id||e._id||e.notificationId,o=e.message||e.text||e.content||"",a=e.type||"notification",n=e.read||e.isRead||0,i=e.date||e.datetime||e.createdDate||new Date().toISOString(),s=e.url||e.link||"";return{id:`${this.sourceName}-${r}`,source:this.sourceName,sourceId:r.toString(),type:a,title:a,message:o,link:s.startsWith("http")?s:`${this.apiUrl}${s.startsWith("/")?"":"/"}${s}`,isRead:1===n||!0===n,timestamp:new Date(i),priority:"normal",user:{id:t,name:e.username||e.userName||""},metadata:{moduleId:e.moduleId||e.module||"",projectId:e.projectId||""}}}):[]}async getUserEmail(){try{let e=await (0,o.getServerSession)(a.N);if(!e||!e.user?.email)return null;return e.user.email}catch(e){return console.error("[LEANTIME_ADAPTER] Error getting user email from session:",e),null}}async getLeantimeUserId(e){try{if(!this.apiToken)return null;let t=await fetch(`${this.apiUrl}/api/jsonrpc`,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.apiToken},body:JSON.stringify({jsonrpc:"2.0",method:"leantime.rpc.users.getAll",id:1})});if(!t.ok)return null;let r=await t.json();if(!r.result||!Array.isArray(r.result))return null;let o=r.result.find(t=>t.username===e||t.email===e||"string"==typeof t.username&&t.username.toLowerCase()===e.toLowerCase());if(o)return o.id;return null}catch(e){return console.error("[LEANTIME_ADAPTER] Error getting Leantime user ID:",e),null}}}var i=r(36781);class s{static{this.NOTIFICATION_COUNT_CACHE_KEY=e=>`notifications:count:${e}`}static{this.NOTIFICATIONS_LIST_CACHE_KEY=(e,t,r)=>`notifications:list:${e}:${t}:${r}`}static{this.COUNT_CACHE_TTL=30}static{this.LIST_CACHE_TTL=300}static{this.REFRESH_LOCK_KEY=e=>`notifications:refresh:lock:${e}`}static{this.REFRESH_LOCK_TTL=30}constructor(){this.adapters=new Map,console.log("[NOTIFICATION_SERVICE] Initializing notification service"),this.registerAdapter(new n),console.log("[NOTIFICATION_SERVICE] Registered adapters:",Array.from(this.adapters.keys()))}static getInstance(){return s.instance||(console.log("[NOTIFICATION_SERVICE] Creating new notification service instance"),s.instance=new s),s.instance}registerAdapter(e){this.adapters.set(e.sourceName,e),console.log(`[NOTIFICATION_SERVICE] Registered notification adapter: ${e.sourceName}`)}async getNotifications(e,t=1,r=20){console.log(`[NOTIFICATION_SERVICE] getNotifications called for user ${e}, page ${t}, limit ${r}`);let o=(0,i.nr)(),a=s.NOTIFICATIONS_LIST_CACHE_KEY(e,t,r);try{let t=await o.get(a);if(t)return console.log(`[NOTIFICATION_SERVICE] Using cached notifications for user ${e}`),await o.ttl(a)<s.LIST_CACHE_TTL/2&&this.scheduleBackgroundRefresh(e),JSON.parse(t)}catch(e){console.error("[NOTIFICATION_SERVICE] Error retrieving notifications from cache:",e)}console.log(`[NOTIFICATION_SERVICE] Fetching notifications for user ${e} from ${this.adapters.size} adapters`);let n=[],l=Array.from(this.adapters.entries());console.log(`[NOTIFICATION_SERVICE] Available adapters: ${l.map(([e])=>e).join(", ")}`);let c=l.map(async([o,a])=>{console.log(`[NOTIFICATION_SERVICE] Checking if adapter ${o} is configured`);try{let n=await a.isConfigured();if(console.log(`[NOTIFICATION_SERVICE] Adapter ${o} is configured: ${n}`),!n)return console.log(`[NOTIFICATION_SERVICE] Skipping adapter ${o} as it is not configured`),[];{console.log(`[NOTIFICATION_SERVICE] Fetching notifications from ${o} for user ${e}`);let n=await a.getNotifications(e,t,r);return console.log(`[NOTIFICATION_SERVICE] Got ${n.length} notifications from ${o}`),n}}catch(e){return console.error(`[NOTIFICATION_SERVICE] Error fetching notifications from ${o}:`,e),[]}});(await Promise.all(c)).forEach((e,t)=>{let r=l[t][0];console.log(`[NOTIFICATION_SERVICE] Adding ${e.length} notifications from ${r}`),n.push(...e)}),n.sort((e,t)=>t.timestamp.getTime()-e.timestamp.getTime()),console.log(`[NOTIFICATION_SERVICE] Total notifications after sorting: ${n.length}`);try{await o.set(a,JSON.stringify(n),"EX",s.LIST_CACHE_TTL),console.log(`[NOTIFICATION_SERVICE] Cached ${n.length} notifications for user ${e}`)}catch(e){console.error("[NOTIFICATION_SERVICE] Error caching notifications:",e)}return n}async getNotificationCount(e){console.log(`[NOTIFICATION_SERVICE] getNotificationCount called for user ${e}`);let t=(0,i.nr)(),r=s.NOTIFICATION_COUNT_CACHE_KEY(e);try{let o=await t.get(r);if(o)return console.log(`[NOTIFICATION_SERVICE] Using cached notification counts for user ${e}`),await t.ttl(r)<s.COUNT_CACHE_TTL/2&&this.scheduleBackgroundRefresh(e),JSON.parse(o)}catch(e){console.error("[NOTIFICATION_SERVICE] Error retrieving notification counts from cache:",e)}console.log(`[NOTIFICATION_SERVICE] Fetching notification counts for user ${e} from ${this.adapters.size} adapters`);let o={total:0,unread:0,sources:{}},a=Array.from(this.adapters.entries());console.log(`[NOTIFICATION_SERVICE] Available adapters for count: ${a.map(([e])=>e).join(", ")}`);let n=a.map(async([t,r])=>{console.log(`[NOTIFICATION_SERVICE] Checking if adapter ${t} is configured for count`);try{let o=await r.isConfigured();if(console.log(`[NOTIFICATION_SERVICE] Adapter ${t} is configured for count: ${o}`),!o)return console.log(`[NOTIFICATION_SERVICE] Skipping adapter ${t} for count as it is not configured`),null;{console.log(`[NOTIFICATION_SERVICE] Fetching notification count from ${t} for user ${e}`);let o=await r.getNotificationCount(e);return console.log(`[NOTIFICATION_SERVICE] Got count from ${t}:`,o),o}}catch(e){return console.error(`[NOTIFICATION_SERVICE] Error fetching notification count from ${t}:`,e),null}});(await Promise.all(n)).forEach((e,t)=>{if(!e)return;let r=a[t][0];console.log(`[NOTIFICATION_SERVICE] Adding counts from ${r}: total=${e.total}, unread=${e.unread}`),o.total+=e.total,o.unread+=e.unread,Object.entries(e.sources).forEach(([e,t])=>{o.sources[e]=t})}),console.log(`[NOTIFICATION_SERVICE] Aggregated counts for user ${e}:`,o);try{await t.set(r,JSON.stringify(o),"EX",s.COUNT_CACHE_TTL),console.log(`[NOTIFICATION_SERVICE] Cached notification counts for user ${e}`)}catch(e){console.error("[NOTIFICATION_SERVICE] Error caching notification counts:",e)}return o}async markAsRead(e,t){let[r,...o]=t.split("-");if(o.join("-"),!r||!this.adapters.has(r))return!1;let a=this.adapters.get(r),n=await a.markAsRead(e,t);return n&&await this.invalidateCache(e),n}async markAllAsRead(e){let t=Array.from(this.adapters.values()).map(t=>t.isConfigured().then(r=>!r||t.markAllAsRead(e)).catch(e=>(console.error(`Error marking all notifications as read for ${t.sourceName}:`,e),!1))),r=(await Promise.all(t)).every(e=>e);return r&&await this.invalidateCache(e),r}async invalidateCache(e){try{let t=(0,i.nr)(),r=s.NOTIFICATION_COUNT_CACHE_KEY(e),o=`notifications:list:${e}:*`;await t.del(r);let a=await t.keys(o);a.length>0&&await t.del(...a),console.log(`[NOTIFICATION_SERVICE] Invalidated notification caches for user ${e}`)}catch(e){console.error("Error invalidating notification caches:",e)}}async scheduleBackgroundRefresh(e){let t=(0,i.nr)(),r=s.REFRESH_LOCK_KEY(e);await t.set(r,Date.now().toString(),"EX",s.REFRESH_LOCK_TTL,"NX")&&setTimeout(async()=>{try{let r=`notifications:last_refresh:${e}`,o=await t.get(r);if(o){let t=parseInt(o,10);if(Date.now()-t<6e4)return void console.log(`[NOTIFICATION_SERVICE] Skipping background refresh for user ${e} - refreshed recently`)}console.log(`[NOTIFICATION_SERVICE] Background refresh started for user ${e}`),await t.set(r,Date.now().toString(),"EX",120),await this.getNotificationCount(e),await this.getNotifications(e,1,20),console.log(`[NOTIFICATION_SERVICE] Background refresh completed for user ${e}`)}catch(t){console.error(`[NOTIFICATION_SERVICE] Background refresh failed for user ${e}:`,t)}finally{await t.del(r).catch(()=>{})}},0)}}},78335:()=>{},96487:()=>{}};