@manojkmfsi/monodog 1.1.28 → 1.1.31

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.
Files changed (31) hide show
  1. package/.env.example +1 -15
  2. package/CHANGELOG.md +76 -0
  3. package/check-db.js +58 -0
  4. package/create-test-session.js +50 -0
  5. package/dev-server.pid +1 -0
  6. package/dist/controllers/auth-controller.js +196 -0
  7. package/dist/controllers/permission-controller.js +152 -0
  8. package/dist/controllers/pipeline-controller.js +329 -0
  9. package/dist/controllers/publish-controller.js +119 -7
  10. package/dist/middleware/auth-middleware.js +1 -0
  11. package/dist/middleware/server-startup.js +19 -0
  12. package/dist/routes/auth-routes.js +7 -336
  13. package/dist/routes/permission-routes.js +4 -139
  14. package/dist/routes/pipeline-routes.js +76 -0
  15. package/dist/services/auth-service.js +239 -0
  16. package/dist/services/changeset-service.js +2 -13
  17. package/dist/services/github-actions-service.js +552 -0
  18. package/dist/services/permission-service.js +30 -0
  19. package/dist/services/pipeline-service.js +356 -0
  20. package/dist/types/github-actions.js +6 -0
  21. package/monodog-dashboard/dist/assets/index-6NrFUGfK.js +15 -0
  22. package/monodog-dashboard/dist/assets/index-6NrFUGfK.js.map +1 -0
  23. package/monodog-dashboard/dist/assets/index-DcvKt8qx.css +1 -0
  24. package/monodog-dashboard/dist/index.html +2 -2
  25. package/package.json +2 -2
  26. package/prisma/migrations/{20260118042615_init_database → 20260224091033_init_db}/migration.sql +58 -0
  27. package/prisma/schema/pipeline-audit-log.prisma +22 -0
  28. package/prisma/schema/release-pipeline.prisma +25 -0
  29. package/monodog-dashboard/dist/assets/index-7G3SCgcz.css +0 -1
  30. package/monodog-dashboard/dist/assets/index-BMoE990p.js +0 -13
  31. package/monodog-dashboard/dist/assets/index-BMoE990p.js.map +0 -1
package/.env.example CHANGED
@@ -1,19 +1,5 @@
1
1
  # GitHub OAuth Configuration
2
2
  GITHUB_CLIENT_ID=your_client_id_here
3
3
  GITHUB_CLIENT_SECRET=your_client_secret_here
4
- OAUTH_REDIRECT_URI=http://localhost:3000/auth/callback
4
+ OAUTH_REDIRECT_URI=http://localhost:3010/auth/callback
5
5
 
6
- # Database Configuration
7
- # DATABASE_URL=postgresql://user:password@localhost:5432/monodog
8
-
9
- # # Server Configuration
10
- # SERVER_HOST=localhost
11
- # SERVER_PORT=5000
12
- # DASHBOARD_HOST=localhost
13
- # DASHBOARD_PORT=3000
14
-
15
- # # Logging Level (debug, info, warn, error)
16
- # LOG_LEVEL=info
17
-
18
- # # Environment
19
- # NODE_ENV=development
package/CHANGELOG.md CHANGED
@@ -1,5 +1,81 @@
1
1
  # @manojkmfsi/monoapp
2
2
 
3
+ ## 1.1.31
4
+
5
+ ### Patch Changes
6
+
7
+ - [`0541cc8`](https://github.com/manojkmfsi/monodog/commit/0541cc88c639265386c29a59b09e6b63cdee6064) - vnbbnbn,n,mnm,m
8
+
9
+ - [`785a90a`](https://github.com/manojkmfsi/monodog/commit/785a90a9c15354559f13a88bf1f9486c9794fc18) - ffhjhkklnbncxdflk,
10
+
11
+ - [`3a32768`](https://github.com/manojkmfsi/monodog/commit/3a32768c4e1be683847d9308632c1d4eb85e43fd) - ccfckjjlkklkm,m.,m.,
12
+
13
+ - [`efee08b`](https://github.com/manojkmfsi/monodog/commit/efee08b5d8cc52f35b7a21dae69ca7dde5b99427) - fgkjlkn,m cgfcbv
14
+
15
+ ## 1.1.30
16
+
17
+ ### Patch Changes
18
+
19
+ - [`f27db43`](https://github.com/manojkmfsi/monodog/commit/f27db43277895381dbf239ffd57ebb17e7fd6e13) - sasasasasasasas
20
+
21
+ ## 1.1.29
22
+
23
+ ### Patch Changes
24
+
25
+ - [`8600e0c`](https://github.com/manojkmfsi/monodog/commit/8600e0c636f76c8b9dcc8fbf7a2617d355f2d0e5) - fsfyfhfhfjjh,m
26
+
27
+ - [`188bcf2`](https://github.com/manojkmfsi/monodog/commit/188bcf2ab06b5fe58b2cea5915a7751cba3a68d2) - cxzcxvxcbvcbnb,m
28
+
29
+ - [`cfb03da`](https://github.com/manojkmfsi/monodog/commit/cfb03da50efd0b829bf4a8b4c5c2ae68c4d1a4ce) - mkjmnmnmnmnnmnm
30
+
31
+ - [`d95b183`](https://github.com/manojkmfsi/monodog/commit/d95b183ea3aa3a60f153d40d1db4049565ecaffa) - m nm nm nm nm mn nm mmm nm mn mm
32
+
33
+ - [`8abe3fb`](https://github.com/manojkmfsi/monodog/commit/8abe3fb09b2608696e6960ac0fdb8e0a9112dfa7) - xzdfdguiulmn cxdtyj
34
+
35
+ - [`9add854`](https://github.com/manojkmfsi/monodog/commit/9add854171041d38161916c2ce5ed34af471614a) - hbmjnbmm,n,,m,
36
+
37
+ - [`5f9b61e`](https://github.com/manojkmfsi/monodog/commit/5f9b61e73c8d1c460dac445aa9c5ae52ed053883) - cxgfhgjmnmnm,k,m
38
+
39
+ - [`bde7bfb`](https://github.com/manojkmfsi/monodog/commit/bde7bfb74376917ab590c8f0d831c3aa0a9e0482) - vnmn,nkjlkn,mnm,
40
+
41
+ - [`e67b026`](https://github.com/manojkmfsi/monodog/commit/e67b02689d82fb4cae0ca917fdb829c3d23d3b9d) - drkjk,,kjudscxvxvvvvnm
42
+
43
+ - [`6b78e09`](https://github.com/manojkmfsi/monodog/commit/6b78e09e6e090ece45485b0e43b1b6e5a537e4eb) - fcdgcbvnkmkllml.m.
44
+
45
+ - [`1a74552`](https://github.com/manojkmfsi/monodog/commit/1a74552277f8deaef831649ad424ea41c77fd467) - nhuyfgxbvnbmklm, .,nmkn,
46
+
47
+ - [`fe566fd`](https://github.com/manojkmfsi/monodog/commit/fe566fdb7041ce079e8afe78ebdb4b477f0cae44) - fghjvvnvnbn
48
+
49
+ - [`79566ae`](https://github.com/manojkmfsi/monodog/commit/79566ae23e3f30a03482134f35b5491e289d2775) - adssdxvcvbcbvcxvcbvcb
50
+
51
+ - [`804ddf2`](https://github.com/manojkmfsi/monodog/commit/804ddf22cf845aa2c980bff9488a04e251be119a) - fxcbcvcxcbvnbvnb
52
+
53
+ - [`07e1878`](https://github.com/manojkmfsi/monodog/commit/07e18786e6f3d8dad57f90822af93bd578c9c3ae) - bvcghmjnm,nmnmhkjhn,mn
54
+
55
+ - [`faa4e0c`](https://github.com/manojkmfsi/monodog/commit/faa4e0cb48e0b1f8eae6aa93f104924452076b94) - mnmmmmnmnmn,mn,mnmn,
56
+
57
+ - [`4ed3483`](https://github.com/manojkmfsi/monodog/commit/4ed34834edea9c6789ffbf93c1354f9752b59b8b) - n,mnmnmnmn,mnm,,m
58
+
59
+ - [`dd47e0b`](https://github.com/manojkmfsi/monodog/commit/dd47e0b8480f14a78b958f3ff68d3b41082f3465) - mnn,mn,mn,n,mn,,
60
+
61
+ - [`621bee1`](https://github.com/manojkmfsi/monodog/commit/621bee11b6194ee56fd90c130a4b3c83b386831a) - kmmnmmn,n,m,m, n,m
62
+
63
+ - [`ec7e1b0`](https://github.com/manojkmfsi/monodog/commit/ec7e1b0817ae540ece67576fbceb7486dcadc48f) - mnm,n,n,mn,mn,m,m,m,
64
+
65
+ - [`411523b`](https://github.com/manojkmfsi/monodog/commit/411523b813a96fcfd46c3e459bcd887c255fd2e7) - mnmn,mn,mn,m.,m.,m.,m,m.,
66
+
67
+ - [`ec19a7c`](https://github.com/manojkmfsi/monodog/commit/ec19a7ccff425f7319c24d0506a147fcfdd0e9ca) - vbcbvbnvnmbnmbnmnm
68
+
69
+ - [`6818670`](https://github.com/manojkmfsi/monodog/commit/6818670424be6bdb98e1fd2e04f1fe985638e67e) - cxxvcvcbvbnvnbvnmnm
70
+
71
+ - [`10eac2e`](https://github.com/manojkmfsi/monodog/commit/10eac2ee72753474d4ec0d9ba2ba3ebdd4639c96) - sdhgjhkjhkjjkkkjn
72
+
73
+ - [`4c924c9`](https://github.com/manojkmfsi/monodog/commit/4c924c918f93cbd54c1c752060a6bdaab45e987d) - wdassdsfddfsdffdgfdsgfsgfg
74
+
75
+ - [`a9e5e26`](https://github.com/manojkmfsi/monodog/commit/a9e5e2680f49c448c49e3a1c414d5c2533a5e9cf) - nnknknnnknkn,,mnm,
76
+
77
+ - [`d559595`](https://github.com/manojkmfsi/monodog/commit/d559595e3b56371a102a21244d0d6c5696541bd3) - dsdsmnd,mns,mnd,msnd,msn,md
78
+
3
79
  ## 1.1.28
4
80
 
5
81
  ### Patch Changes
package/check-db.js ADDED
@@ -0,0 +1,58 @@
1
+ const { PrismaClient } = require('@prisma/client');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+
5
+ // Load config similar to the app
6
+ let databasePath = 'file:./monodog.db'; // default
7
+
8
+ // Try to read monodog-config.json
9
+ try {
10
+ const configPath = path.join(__dirname, 'monodog-config.json');
11
+ if (fs.existsSync(configPath)) {
12
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
13
+ databasePath = config.database?.path || databasePath;
14
+ }
15
+ } catch (e) {
16
+ console.warn('Could not read config:', e.message);
17
+ }
18
+
19
+ console.log(`Database URL: ${databasePath}\n`);
20
+
21
+ async function checkDatabase() {
22
+ const prisma = new PrismaClient({
23
+ datasources: {
24
+ db: {
25
+ url: databasePath,
26
+ },
27
+ },
28
+ });
29
+
30
+ try {
31
+ console.log('=== Database Status ===\n');
32
+
33
+ // Check ReleasePipeline count
34
+ const pipelineCount = await prisma.releasePipeline.count();
35
+ console.log(`Total pipelines in database: ${pipelineCount}\n`);
36
+
37
+ if (pipelineCount > 0) {
38
+ const pipelines = await prisma.releasePipeline.findMany({
39
+ take: 5,
40
+ orderBy: { createdAt: 'desc' },
41
+ });
42
+ console.log('Latest pipelines:');
43
+ pipelines.forEach(p => {
44
+ console.log(` - ${p.packageName} v${p.releaseVersion} (${p.currentStatus})`);
45
+ console.log(` Triggered by: ${p.triggeredBy} at ${p.triggeredAt}`);
46
+ console.log(` Owner/Repo: ${p.owner}/${p.repo}`);
47
+ console.log('');
48
+ });
49
+ }
50
+
51
+ process.exit(0);
52
+ } catch (error) {
53
+ console.error('Error:', error.message);
54
+ process.exit(1);
55
+ }
56
+ }
57
+
58
+ checkDatabase();
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * This script creates a test session by directly calling the auth middleware's storeSession function
5
+ * It simulates what happens after a successful GitHub OAuth login
6
+ */
7
+
8
+ const { storeSession } = require('./dist/middleware/auth-middleware');
9
+
10
+ // Create a mock session
11
+ const mockSession = {
12
+ accessToken: 'gho_test_token_' + Math.random().toString(36).substr(2, 9),
13
+ expiresIn: 3600,
14
+ expiresAt: Date.now() + 24 * 60 * 60 * 1000,
15
+ user: {
16
+ id: 12345,
17
+ login: 'testuser',
18
+ name: 'Test User',
19
+ email: 'test@example.com',
20
+ avatar_url: 'https://avatars.githubusercontent.com/u/12345?v=4',
21
+ public_repos: 5,
22
+ followers: 10,
23
+ following: 5,
24
+ },
25
+ scopes: ['repo', 'read:user'],
26
+ permission: {
27
+ permission: 'maintain',
28
+ role: 'Maintainer',
29
+ userId: 12345,
30
+ username: 'testuser',
31
+ owner: 'manojkmfsi',
32
+ repo: 'MonoDog',
33
+ cachedAt: Date.now(),
34
+ ttl: 3600000,
35
+ },
36
+ };
37
+
38
+ try {
39
+ const token = storeSession(mockSession);
40
+ console.log('✅ Test session created successfully!');
41
+ console.log(`\nSession Token: ${token}`);
42
+ console.log(`User: ${mockSession.user.login}`);
43
+ console.log(`Permission: ${mockSession.permission.permission}`);
44
+ console.log(`Expires at: ${new Date(mockSession.expiresAt).toISOString()}`);
45
+ console.log(`\nYou can use this token in API requests:`);
46
+ console.log(`curl -H "Authorization: Bearer ${token}" http://localhost:8999/api/publish/trigger`);
47
+ } catch (error) {
48
+ console.error('❌ Failed to create session:', error.message);
49
+ process.exit(1);
50
+ }
package/dev-server.pid ADDED
@@ -0,0 +1 @@
1
+ 22401
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ /**
3
+ * Authentication Controller
4
+ * Thin controller that handles HTTP concerns and delegates business logic to auth-service
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.refresh = exports.logout = exports.validate = exports.me = exports.callback = exports.login = void 0;
8
+ const auth_service_1 = require("../services/auth-service");
9
+ const logger_1 = require("../middleware/logger");
10
+ /**
11
+ * Start OAuth login flow
12
+ * GET /auth/login
13
+ */
14
+ const login = (req, res) => {
15
+ try {
16
+ const redirectUrl = req.query.redirect || '/';
17
+ const result = (0, auth_service_1.initiateLogin)(redirectUrl);
18
+ res.json({
19
+ success: true,
20
+ authUrl: result.authUrl,
21
+ message: 'Redirect to this URL to authenticate with GitHub',
22
+ });
23
+ }
24
+ catch (error) {
25
+ logger_1.AppLogger.error(`Login initiation failed: ${error}`);
26
+ res.status(500).json({
27
+ success: false,
28
+ error: 'Login failed',
29
+ message: error instanceof Error ? error.message : 'Failed to initiate GitHub OAuth flow',
30
+ });
31
+ }
32
+ };
33
+ exports.login = login;
34
+ /**
35
+ * OAuth callback handler
36
+ * GET /auth/callback?code=...&state=...
37
+ */
38
+ const callback = async (req, res) => {
39
+ try {
40
+ const { code, state, error, error_description } = req.query;
41
+ // Handle OAuth errors from GitHub
42
+ if (error) {
43
+ logger_1.AppLogger.warn(`OAuth error: ${error} - ${error_description}`);
44
+ res.status(400).json({
45
+ success: false,
46
+ error: error,
47
+ message: error_description,
48
+ });
49
+ return;
50
+ }
51
+ if (!code || !state) {
52
+ logger_1.AppLogger.warn('OAuth callback missing code or state');
53
+ res.status(400).json({
54
+ success: false,
55
+ error: 'Missing parameters',
56
+ message: 'OAuth code and state are required',
57
+ });
58
+ return;
59
+ }
60
+ const result = await (0, auth_service_1.handleOAuthCallback)(code, state);
61
+ res.json({
62
+ success: true,
63
+ message: 'Authentication successful',
64
+ ...result,
65
+ });
66
+ }
67
+ catch (error) {
68
+ logger_1.AppLogger.error(`OAuth callback failed: ${error}`);
69
+ const message = error instanceof Error ? error.message : 'Failed to complete GitHub OAuth flow';
70
+ if (message.includes('CSRF')) {
71
+ res.status(400).json({
72
+ success: false,
73
+ error: 'Invalid state',
74
+ message,
75
+ });
76
+ }
77
+ else {
78
+ res.status(500).json({
79
+ success: false,
80
+ error: 'Authentication failed',
81
+ message,
82
+ });
83
+ }
84
+ }
85
+ };
86
+ exports.callback = callback;
87
+ /**
88
+ * Get current user session
89
+ * GET /auth/me
90
+ */
91
+ const me = (req, res) => {
92
+ try {
93
+ const session = (0, auth_service_1.getCurrentSession)(req);
94
+ res.json({
95
+ success: true,
96
+ ...session,
97
+ });
98
+ }
99
+ catch (error) {
100
+ logger_1.AppLogger.error(`Failed to get user session: ${error}`);
101
+ res.status(401).json({
102
+ success: false,
103
+ error: 'Unauthorized',
104
+ message: error instanceof Error ? error.message : 'Failed to retrieve user information',
105
+ });
106
+ }
107
+ };
108
+ exports.me = me;
109
+ /**
110
+ * Validate session
111
+ * POST /auth/validate
112
+ */
113
+ const validate = async (req, res) => {
114
+ try {
115
+ const result = await (0, auth_service_1.validateCurrentSession)(req);
116
+ res.json({
117
+ success: true,
118
+ ...result,
119
+ message: 'Session is valid',
120
+ });
121
+ }
122
+ catch (error) {
123
+ logger_1.AppLogger.error(`Session validation failed: ${error}`);
124
+ if (error instanceof Error && error.message.includes('no longer valid')) {
125
+ res.status(401).json({
126
+ success: false,
127
+ valid: false,
128
+ error: 'Unauthorized',
129
+ message: error.message,
130
+ });
131
+ }
132
+ else {
133
+ res.status(500).json({
134
+ success: false,
135
+ valid: false,
136
+ error: 'Validation failed',
137
+ message: error instanceof Error ? error.message : 'Failed to validate session',
138
+ });
139
+ }
140
+ }
141
+ };
142
+ exports.validate = validate;
143
+ /**
144
+ * Logout
145
+ * POST /auth/logout
146
+ */
147
+ const logout = (req, res) => {
148
+ try {
149
+ (0, auth_service_1.logoutUser)(req);
150
+ res.json({
151
+ success: true,
152
+ message: 'Logout successful',
153
+ });
154
+ }
155
+ catch (error) {
156
+ logger_1.AppLogger.error(`Logout failed: ${error}`);
157
+ res.status(500).json({
158
+ success: false,
159
+ error: 'Logout failed',
160
+ message: error instanceof Error ? error.message : 'Failed to logout',
161
+ });
162
+ }
163
+ };
164
+ exports.logout = logout;
165
+ /**
166
+ * Refresh session (token)
167
+ * POST /auth/refresh
168
+ */
169
+ const refresh = async (req, res) => {
170
+ try {
171
+ const result = await (0, auth_service_1.refreshUserSession)(req);
172
+ res.json({
173
+ success: true,
174
+ message: 'Session refreshed successfully',
175
+ ...result,
176
+ });
177
+ }
178
+ catch (error) {
179
+ logger_1.AppLogger.error(`Session refresh failed: ${error}`);
180
+ if (error instanceof Error && error.message.includes('no longer valid')) {
181
+ res.status(401).json({
182
+ success: false,
183
+ error: 'Unauthorized',
184
+ message: error.message,
185
+ });
186
+ }
187
+ else {
188
+ res.status(500).json({
189
+ success: false,
190
+ error: 'Refresh failed',
191
+ message: error instanceof Error ? error.message : 'Failed to refresh session',
192
+ });
193
+ }
194
+ }
195
+ };
196
+ exports.refresh = refresh;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * Permission Controller
4
+ * Thin controller that handles HTTP concerns and delegates business logic to permission-service
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.invalidateCache = exports.checkActionPermission = exports.getRepositoryPermission = void 0;
8
+ const auth_middleware_1 = require("../middleware/auth-middleware");
9
+ const permission_service_1 = require("../services/permission-service");
10
+ const logger_1 = require("../middleware/logger");
11
+ /**
12
+ * Get user's permission for a specific repository
13
+ * GET /permissions/:owner/:repo
14
+ */
15
+ const getRepositoryPermission = async (req, res) => {
16
+ try {
17
+ const session = (0, auth_middleware_1.getSessionFromRequest)(req);
18
+ if (!session) {
19
+ res.status(401).json({
20
+ success: false,
21
+ error: 'Unauthorized',
22
+ message: 'No active session',
23
+ });
24
+ return;
25
+ }
26
+ const { owner, repo } = req.params;
27
+ const forceRefresh = req.query.refresh === 'true';
28
+ if (!owner || !repo) {
29
+ res.status(400).json({
30
+ success: false,
31
+ error: 'Bad request',
32
+ message: 'Owner and repo parameters are required',
33
+ });
34
+ return;
35
+ }
36
+ logger_1.AppLogger.debug(`Checking permission for ${session.user.login} in ${owner}/${repo}`);
37
+ const permissionCheck = await (0, permission_service_1.checkRepositoryPermission)(session.accessToken, session.user.id, session.user.login, owner, repo, forceRefresh);
38
+ res.json({
39
+ success: true,
40
+ owner,
41
+ repo,
42
+ user: session.user.login,
43
+ ...permissionCheck,
44
+ });
45
+ }
46
+ catch (error) {
47
+ logger_1.AppLogger.error(`Failed to check permission: ${error}`);
48
+ res.status(500).json({
49
+ success: false,
50
+ error: 'Internal server error',
51
+ message: 'Failed to check repository permission',
52
+ });
53
+ }
54
+ };
55
+ exports.getRepositoryPermission = getRepositoryPermission;
56
+ /**
57
+ * Check if user can perform a specific action
58
+ * POST /permissions/:owner/:repo/can-action
59
+ */
60
+ const checkActionPermission = async (req, res) => {
61
+ try {
62
+ const session = (0, auth_middleware_1.getSessionFromRequest)(req);
63
+ if (!session) {
64
+ res.status(401).json({
65
+ success: false,
66
+ error: 'Unauthorized',
67
+ message: 'No active session',
68
+ });
69
+ return;
70
+ }
71
+ const { owner, repo } = req.params;
72
+ const { action } = req.body;
73
+ if (!owner || !repo) {
74
+ res.status(400).json({
75
+ success: false,
76
+ error: 'Bad request',
77
+ message: 'Owner and repo parameters are required',
78
+ });
79
+ return;
80
+ }
81
+ if (!action || !['read', 'write', 'maintain', 'admin'].includes(action)) {
82
+ res.status(400).json({
83
+ success: false,
84
+ error: 'Bad request',
85
+ message: 'Valid action is required (read, write, maintain, or admin)',
86
+ });
87
+ return;
88
+ }
89
+ logger_1.AppLogger.debug(`Checking if ${session.user.login} can perform '${action}' in ${owner}/${repo}`);
90
+ const actionCheck = await (0, permission_service_1.checkUserAction)(session.accessToken, session.user.id, session.user.login, owner, repo, action);
91
+ res.json({
92
+ success: true,
93
+ owner,
94
+ repo,
95
+ user: session.user.login,
96
+ ...actionCheck,
97
+ });
98
+ }
99
+ catch (error) {
100
+ logger_1.AppLogger.error(`Failed to check action permission: ${error}`);
101
+ res.status(500).json({
102
+ success: false,
103
+ error: 'Internal server error',
104
+ message: 'Failed to check action permission',
105
+ });
106
+ }
107
+ };
108
+ exports.checkActionPermission = checkActionPermission;
109
+ /**
110
+ * Invalidate permission cache for a repository
111
+ * POST /permissions/:owner/:repo/invalidate
112
+ */
113
+ const invalidateCache = (req, res) => {
114
+ try {
115
+ const session = (0, auth_middleware_1.getSessionFromRequest)(req);
116
+ if (!session) {
117
+ res.status(401).json({
118
+ success: false,
119
+ error: 'Unauthorized',
120
+ message: 'No active session',
121
+ });
122
+ return;
123
+ }
124
+ const { owner, repo } = req.params;
125
+ if (!owner || !repo) {
126
+ res.status(400).json({
127
+ success: false,
128
+ error: 'Bad request',
129
+ message: 'Owner and repo parameters are required',
130
+ });
131
+ return;
132
+ }
133
+ logger_1.AppLogger.debug(`Invalidating permission cache for ${session.user.login} in ${owner}/${repo}`);
134
+ (0, permission_service_1.invalidatePermissionCache)(session.user.id, owner, repo);
135
+ res.json({
136
+ success: true,
137
+ message: 'Permission cache invalidated',
138
+ owner,
139
+ repo,
140
+ user: session.user.login,
141
+ });
142
+ }
143
+ catch (error) {
144
+ logger_1.AppLogger.error(`Failed to invalidate cache: ${error}`);
145
+ res.status(500).json({
146
+ success: false,
147
+ error: 'Internal server error',
148
+ message: 'Failed to invalidate permission cache',
149
+ });
150
+ }
151
+ };
152
+ exports.invalidateCache = invalidateCache;