yt-transcript-strapi-plugin 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -975,6 +975,26 @@ const controller = ({ strapi }) => ({
975
975
  ctx.body = { data: transcript2 };
976
976
  }
977
977
  });
978
+ const SESSION_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
979
+ function isSessionExpired(session) {
980
+ return Date.now() - session.createdAt > SESSION_TIMEOUT_MS;
981
+ }
982
+ function cleanupExpiredSessions(plugin, strapi) {
983
+ let cleaned = 0;
984
+ for (const [sessionId, session] of plugin.sessions.entries()) {
985
+ if (isSessionExpired(session)) {
986
+ try {
987
+ session.server.close();
988
+ } catch {
989
+ }
990
+ plugin.sessions.delete(sessionId);
991
+ cleaned++;
992
+ }
993
+ }
994
+ if (cleaned > 0) {
995
+ strapi.log.debug(`[yt-transcript-mcp] Cleaned up ${cleaned} expired sessions`);
996
+ }
997
+ }
978
998
  const mcpController = ({ strapi }) => ({
979
999
  /**
980
1000
  * Handle MCP requests (POST, GET, DELETE)
@@ -992,10 +1012,35 @@ const mcpController = ({ strapi }) => ({
992
1012
  return;
993
1013
  }
994
1014
  const strapiToken = ctx.state.strapiToken;
1015
+ if (Math.random() < 0.01) {
1016
+ cleanupExpiredSessions(plugin, strapi);
1017
+ }
995
1018
  try {
996
- const sessionId = ctx.request.headers["mcp-session-id"] || node_crypto.randomUUID();
997
- let session = plugin.sessions.get(sessionId);
1019
+ const requestedSessionId = ctx.request.headers["mcp-session-id"];
1020
+ let session = requestedSessionId ? plugin.sessions.get(requestedSessionId) : null;
1021
+ if (session && isSessionExpired(session)) {
1022
+ strapi.log.debug(`[yt-transcript-mcp] Session expired, removing: ${requestedSessionId}`);
1023
+ try {
1024
+ session.server.close();
1025
+ } catch {
1026
+ }
1027
+ plugin.sessions.delete(requestedSessionId);
1028
+ session = null;
1029
+ }
1030
+ if (requestedSessionId && !session) {
1031
+ ctx.status = 400;
1032
+ ctx.body = {
1033
+ jsonrpc: "2.0",
1034
+ error: {
1035
+ code: -32e3,
1036
+ message: "Session expired or invalid. Please reinitialize the connection."
1037
+ },
1038
+ id: null
1039
+ };
1040
+ return;
1041
+ }
998
1042
  if (!session) {
1043
+ const sessionId = node_crypto.randomUUID();
999
1044
  const server = plugin.createMcpServer();
1000
1045
  const transport = new streamableHttp_js.StreamableHTTPServerTransport({
1001
1046
  sessionIdGenerator: () => sessionId
@@ -974,6 +974,26 @@ const controller = ({ strapi }) => ({
974
974
  ctx.body = { data: transcript2 };
975
975
  }
976
976
  });
977
+ const SESSION_TIMEOUT_MS = 4 * 60 * 60 * 1e3;
978
+ function isSessionExpired(session) {
979
+ return Date.now() - session.createdAt > SESSION_TIMEOUT_MS;
980
+ }
981
+ function cleanupExpiredSessions(plugin, strapi) {
982
+ let cleaned = 0;
983
+ for (const [sessionId, session] of plugin.sessions.entries()) {
984
+ if (isSessionExpired(session)) {
985
+ try {
986
+ session.server.close();
987
+ } catch {
988
+ }
989
+ plugin.sessions.delete(sessionId);
990
+ cleaned++;
991
+ }
992
+ }
993
+ if (cleaned > 0) {
994
+ strapi.log.debug(`[yt-transcript-mcp] Cleaned up ${cleaned} expired sessions`);
995
+ }
996
+ }
977
997
  const mcpController = ({ strapi }) => ({
978
998
  /**
979
999
  * Handle MCP requests (POST, GET, DELETE)
@@ -991,10 +1011,35 @@ const mcpController = ({ strapi }) => ({
991
1011
  return;
992
1012
  }
993
1013
  const strapiToken = ctx.state.strapiToken;
1014
+ if (Math.random() < 0.01) {
1015
+ cleanupExpiredSessions(plugin, strapi);
1016
+ }
994
1017
  try {
995
- const sessionId = ctx.request.headers["mcp-session-id"] || randomUUID();
996
- let session = plugin.sessions.get(sessionId);
1018
+ const requestedSessionId = ctx.request.headers["mcp-session-id"];
1019
+ let session = requestedSessionId ? plugin.sessions.get(requestedSessionId) : null;
1020
+ if (session && isSessionExpired(session)) {
1021
+ strapi.log.debug(`[yt-transcript-mcp] Session expired, removing: ${requestedSessionId}`);
1022
+ try {
1023
+ session.server.close();
1024
+ } catch {
1025
+ }
1026
+ plugin.sessions.delete(requestedSessionId);
1027
+ session = null;
1028
+ }
1029
+ if (requestedSessionId && !session) {
1030
+ ctx.status = 400;
1031
+ ctx.body = {
1032
+ jsonrpc: "2.0",
1033
+ error: {
1034
+ code: -32e3,
1035
+ message: "Session expired or invalid. Please reinitialize the connection."
1036
+ },
1037
+ id: null
1038
+ };
1039
+ return;
1040
+ }
997
1041
  if (!session) {
1042
+ const sessionId = randomUUID();
998
1043
  const server = plugin.createMcpServer();
999
1044
  const transport = new StreamableHTTPServerTransport({
1000
1045
  sessionIdGenerator: () => sessionId
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.0",
2
+ "version": "0.1.1",
3
3
  "keywords": [
4
4
  "yt-transcript-strapi-plugin",
5
5
  "youtube",