@sena-ai/platform-core 1.4.0
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.
- package/dist/app.d.ts +9 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +147 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/handler.d.ts +19 -0
- package/dist/auth/handler.d.ts.map +1 -0
- package/dist/auth/handler.js +213 -0
- package/dist/auth/handler.js.map +1 -0
- package/dist/auth/session.d.ts +16 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +54 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/db/d1/index.d.ts +14 -0
- package/dist/db/d1/index.d.ts.map +1 -0
- package/dist/db/d1/index.js +252 -0
- package/dist/db/d1/index.js.map +1 -0
- package/dist/db/d1/schema.d.ts +610 -0
- package/dist/db/d1/schema.d.ts.map +1 -0
- package/dist/db/d1/schema.js +58 -0
- package/dist/db/d1/schema.js.map +1 -0
- package/dist/db/mysql/index.d.ts +14 -0
- package/dist/db/mysql/index.d.ts.map +1 -0
- package/dist/db/mysql/index.js +248 -0
- package/dist/db/mysql/index.js.map +1 -0
- package/dist/db/mysql/schema.d.ts +562 -0
- package/dist/db/mysql/schema.d.ts.map +1 -0
- package/dist/db/mysql/schema.js +61 -0
- package/dist/db/mysql/schema.js.map +1 -0
- package/dist/db/postgresql/index.d.ts +14 -0
- package/dist/db/postgresql/index.d.ts.map +1 -0
- package/dist/db/postgresql/index.js +246 -0
- package/dist/db/postgresql/index.js.map +1 -0
- package/dist/db/postgresql/schema.d.ts +591 -0
- package/dist/db/postgresql/schema.d.ts.map +1 -0
- package/dist/db/postgresql/schema.js +64 -0
- package/dist/db/postgresql/schema.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/relay/api-proxy.d.ts +10 -0
- package/dist/relay/api-proxy.d.ts.map +1 -0
- package/dist/relay/api-proxy.js +40 -0
- package/dist/relay/api-proxy.js.map +1 -0
- package/dist/runtime/cf/crypto.d.ts +7 -0
- package/dist/runtime/cf/crypto.d.ts.map +1 -0
- package/dist/runtime/cf/crypto.js +48 -0
- package/dist/runtime/cf/crypto.js.map +1 -0
- package/dist/runtime/cf/index.d.ts +20 -0
- package/dist/runtime/cf/index.d.ts.map +1 -0
- package/dist/runtime/cf/index.js +14 -0
- package/dist/runtime/cf/index.js.map +1 -0
- package/dist/runtime/cf/relay.d.ts +11 -0
- package/dist/runtime/cf/relay.d.ts.map +1 -0
- package/dist/runtime/cf/relay.js +57 -0
- package/dist/runtime/cf/relay.js.map +1 -0
- package/dist/runtime/cf/vault.d.ts +7 -0
- package/dist/runtime/cf/vault.d.ts.map +1 -0
- package/dist/runtime/cf/vault.js +68 -0
- package/dist/runtime/cf/vault.js.map +1 -0
- package/dist/runtime/node/crypto.d.ts +6 -0
- package/dist/runtime/node/crypto.d.ts.map +1 -0
- package/dist/runtime/node/crypto.js +26 -0
- package/dist/runtime/node/crypto.js.map +1 -0
- package/dist/runtime/node/index.d.ts +17 -0
- package/dist/runtime/node/index.d.ts.map +1 -0
- package/dist/runtime/node/index.js +14 -0
- package/dist/runtime/node/index.js.map +1 -0
- package/dist/runtime/node/relay.d.ts +6 -0
- package/dist/runtime/node/relay.d.ts.map +1 -0
- package/dist/runtime/node/relay.js +73 -0
- package/dist/runtime/node/relay.js.map +1 -0
- package/dist/runtime/node/vault.d.ts +7 -0
- package/dist/runtime/node/vault.d.ts.map +1 -0
- package/dist/runtime/node/vault.js +41 -0
- package/dist/runtime/node/vault.js.map +1 -0
- package/dist/slack/events.d.ts +15 -0
- package/dist/slack/events.d.ts.map +1 -0
- package/dist/slack/events.js +63 -0
- package/dist/slack/events.js.map +1 -0
- package/dist/slack/oauth.d.ts +13 -0
- package/dist/slack/oauth.d.ts.map +1 -0
- package/dist/slack/oauth.js +90 -0
- package/dist/slack/oauth.js.map +1 -0
- package/dist/slack/provisioner.d.ts +60 -0
- package/dist/slack/provisioner.d.ts.map +1 -0
- package/dist/slack/provisioner.js +156 -0
- package/dist/slack/provisioner.js.map +1 -0
- package/dist/types/crypto.d.ts +15 -0
- package/dist/types/crypto.d.ts.map +1 -0
- package/dist/types/crypto.js +2 -0
- package/dist/types/crypto.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/platform.d.ts +25 -0
- package/dist/types/platform.d.ts.map +1 -0
- package/dist/types/platform.js +2 -0
- package/dist/types/platform.js.map +1 -0
- package/dist/types/relay.d.ts +16 -0
- package/dist/types/relay.d.ts.map +1 -0
- package/dist/types/relay.js +2 -0
- package/dist/types/relay.js.map +1 -0
- package/dist/types/repository.d.ts +78 -0
- package/dist/types/repository.d.ts.map +1 -0
- package/dist/types/repository.js +6 -0
- package/dist/types/repository.js.map +1 -0
- package/dist/types/vault.d.ts +9 -0
- package/dist/types/vault.d.ts.map +1 -0
- package/dist/types/vault.js +2 -0
- package/dist/types/vault.js.map +1 -0
- package/dist/web/api.d.ts +9 -0
- package/dist/web/api.d.ts.map +1 -0
- package/dist/web/api.js +144 -0
- package/dist/web/api.js.map +1 -0
- package/dist/web/pages.d.ts +4 -0
- package/dist/web/pages.d.ts.map +1 -0
- package/dist/web/pages.js +401 -0
- package/dist/web/pages.js.map +1 -0
- package/dist/web/setup.d.ts +5 -0
- package/dist/web/setup.d.ts.map +1 -0
- package/dist/web/setup.js +208 -0
- package/dist/web/setup.js.map +1 -0
- package/package.json +46 -0
- package/src/app.ts +221 -0
- package/src/auth/handler.ts +343 -0
- package/src/auth/session.ts +89 -0
- package/src/db/d1/index.ts +304 -0
- package/src/db/d1/schema.ts +62 -0
- package/src/db/mysql/index.ts +301 -0
- package/src/db/mysql/schema.ts +78 -0
- package/src/db/postgresql/index.ts +311 -0
- package/src/db/postgresql/schema.ts +82 -0
- package/src/index.ts +21 -0
- package/src/relay/api-proxy.ts +61 -0
- package/src/runtime/cf/crypto.ts +74 -0
- package/src/runtime/cf/index.ts +31 -0
- package/src/runtime/cf/relay.ts +74 -0
- package/src/runtime/cf/vault.ts +99 -0
- package/src/runtime/node/crypto.ts +33 -0
- package/src/runtime/node/index.ts +28 -0
- package/src/runtime/node/relay.ts +98 -0
- package/src/runtime/node/vault.ts +50 -0
- package/src/slack/events.ts +92 -0
- package/src/slack/oauth.ts +127 -0
- package/src/slack/provisioner.ts +256 -0
- package/src/types/crypto.ts +14 -0
- package/src/types/index.ts +14 -0
- package/src/types/platform.ts +31 -0
- package/src/types/relay.ts +16 -0
- package/src/types/repository.ts +93 -0
- package/src/types/vault.ts +8 -0
- package/src/web/api.ts +204 -0
- package/src/web/pages.ts +458 -0
- package/src/web/setup.ts +270 -0
- package/tsconfig.json +19 -0
- package/tsconfig.tsbuildinfo +1 -0
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { Platform, AppConfig } from './types/platform.js';
|
|
3
|
+
import { type Provisioner } from './slack/provisioner.js';
|
|
4
|
+
export interface CreateAppResult {
|
|
5
|
+
app: Hono;
|
|
6
|
+
provisioner: Provisioner;
|
|
7
|
+
}
|
|
8
|
+
export declare function createApp(platform: Platform, config: AppConfig): CreateAppResult;
|
|
9
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAI9D,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAM5E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,IAAI,CAAA;IACT,WAAW,EAAE,WAAW,CAAA;CACzB;AAgFD,wBAAgB,SAAS,CACvB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,SAAS,GAChB,eAAe,CA0HjB"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { logger } from 'hono/logger';
|
|
3
|
+
import { createApiProxy } from './relay/api-proxy.js';
|
|
4
|
+
import { createSlackEventsHandler } from './slack/events.js';
|
|
5
|
+
import { createOAuthHandler } from './slack/oauth.js';
|
|
6
|
+
import { createProvisioner } from './slack/provisioner.js';
|
|
7
|
+
import { createAuthHandler, createAuthMiddleware } from './auth/handler.js';
|
|
8
|
+
import { createWebApi } from './web/api.js';
|
|
9
|
+
import { createPages } from './web/pages.js';
|
|
10
|
+
import { createSetupPage } from './web/setup.js';
|
|
11
|
+
/**
|
|
12
|
+
* Create the main Hono application with all routes wired up.
|
|
13
|
+
* Works in both Node.js and CF Workers environments.
|
|
14
|
+
*/
|
|
15
|
+
function generateInstallScript() {
|
|
16
|
+
return `#!/bin/sh
|
|
17
|
+
set -e
|
|
18
|
+
|
|
19
|
+
# sena-ai bot bootstrap script
|
|
20
|
+
# Usage: curl -fsSL <platform-url>/install.sh | sh -s -- --name "봇이름" --bot-username "lily-bot" --connect-key "cpk_..." --platform-url "https://..."
|
|
21
|
+
|
|
22
|
+
BOT_NAME=""
|
|
23
|
+
BOT_USERNAME=""
|
|
24
|
+
CONNECT_KEY=""
|
|
25
|
+
PLATFORM_URL=""
|
|
26
|
+
|
|
27
|
+
while [ \$# -gt 0 ]; do
|
|
28
|
+
case "\$1" in
|
|
29
|
+
--name) BOT_NAME="\$2"; shift 2;;
|
|
30
|
+
--bot-username) BOT_USERNAME="\$2"; shift 2;;
|
|
31
|
+
--connect-key) CONNECT_KEY="\$2"; shift 2;;
|
|
32
|
+
--platform-url) PLATFORM_URL="\$2"; shift 2;;
|
|
33
|
+
*) echo "Unknown option: \$1"; exit 1;;
|
|
34
|
+
esac
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
if [ -z "\$BOT_NAME" ] || [ -z "\$BOT_USERNAME" ] || [ -z "\$CONNECT_KEY" ] || [ -z "\$PLATFORM_URL" ]; then
|
|
38
|
+
echo "Error: --name, --bot-username, --connect-key, --platform-url are all required."
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
DIR_NAME="\$BOT_USERNAME"
|
|
43
|
+
|
|
44
|
+
echo "🤖 Setting up bot: \$BOT_NAME"
|
|
45
|
+
echo " Directory: ./\$DIR_NAME"
|
|
46
|
+
echo ""
|
|
47
|
+
|
|
48
|
+
# Download template from GitHub
|
|
49
|
+
echo "📦 Downloading bot template..."
|
|
50
|
+
TMPDIR_DL=\$(mktemp -d)
|
|
51
|
+
curl -fsSL https://github.com/unlimiting-studio/sena-ai/archive/refs/heads/main.tar.gz -o "\$TMPDIR_DL/repo.tar.gz"
|
|
52
|
+
tar xzf "\$TMPDIR_DL/repo.tar.gz" -C "\$TMPDIR_DL"
|
|
53
|
+
|
|
54
|
+
# Copy template directory
|
|
55
|
+
cp -r "\$TMPDIR_DL/sena-ai-main/templates/bot-starter" "\$DIR_NAME"
|
|
56
|
+
rm -rf "\$TMPDIR_DL"
|
|
57
|
+
|
|
58
|
+
cd "\$DIR_NAME"
|
|
59
|
+
|
|
60
|
+
# Escape special characters for sed replacement
|
|
61
|
+
escape_sed() {
|
|
62
|
+
printf '%s' "\$1" | sed 's/[&/\\]/\\&/g'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Customize package.json name
|
|
66
|
+
ESCAPED_DIR=\$(escape_sed "\$DIR_NAME")
|
|
67
|
+
sed -i.bak "s/\\"sena-bot\\"/\\"\$ESCAPED_DIR\\"/" package.json && rm -f package.json.bak
|
|
68
|
+
|
|
69
|
+
# Replace bot name placeholder in sena.config.ts
|
|
70
|
+
ESCAPED_NAME=\$(escape_sed "\$BOT_NAME")
|
|
71
|
+
sed -i.bak "s/%%BOT_NAME%%/\$ESCAPED_NAME/" sena.config.ts && rm -f sena.config.ts.bak
|
|
72
|
+
|
|
73
|
+
# Create .env from template
|
|
74
|
+
ESCAPED_KEY=\$(escape_sed "\$CONNECT_KEY")
|
|
75
|
+
sed -e "s/%%CONNECT_KEY%%/\$ESCAPED_KEY/" -e "s|%%PLATFORM_URL%%|\$PLATFORM_URL|" .env.template > .env
|
|
76
|
+
rm -f .env.template
|
|
77
|
+
|
|
78
|
+
echo ""
|
|
79
|
+
echo "✅ Bot scaffolding complete!"
|
|
80
|
+
echo ""
|
|
81
|
+
echo "Next steps:"
|
|
82
|
+
echo " cd \$DIR_NAME"
|
|
83
|
+
echo " pnpm install"
|
|
84
|
+
echo " npx sena start"
|
|
85
|
+
echo ""
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
export function createApp(platform, config) {
|
|
89
|
+
const app = new Hono();
|
|
90
|
+
app.use('*', logger());
|
|
91
|
+
const provisioner = createProvisioner(platform.bots, platform.configTokens, platform.vault, config.platformBaseUrl);
|
|
92
|
+
const authMiddleware = createAuthMiddleware(platform.workspaceAdminConfig, platform.vault);
|
|
93
|
+
// Serve bootstrap script at /install.sh
|
|
94
|
+
app.get('/install.sh', (c) => {
|
|
95
|
+
c.header('Content-Type', 'text/plain; charset=utf-8');
|
|
96
|
+
return c.body(generateInstallScript());
|
|
97
|
+
});
|
|
98
|
+
// Health check
|
|
99
|
+
app.get('/health', (c) => c.json({
|
|
100
|
+
ok: true,
|
|
101
|
+
connectedBots: platform.relay.connectedBots().length,
|
|
102
|
+
ts: new Date().toISOString(),
|
|
103
|
+
}));
|
|
104
|
+
// SSE/WebSocket relay stream endpoint
|
|
105
|
+
app.get('/relay/stream', async (c) => {
|
|
106
|
+
const connectKey = c.req.header('x-connect-key') || c.req.query('connect_key');
|
|
107
|
+
if (!connectKey) {
|
|
108
|
+
return c.json({ error: 'missing connect_key' }, 401);
|
|
109
|
+
}
|
|
110
|
+
const bot = await platform.bots.findByConnectKeyAndStatus(connectKey, 'active');
|
|
111
|
+
if (!bot) {
|
|
112
|
+
return c.json({ error: 'invalid connect_key or bot not active' }, 401);
|
|
113
|
+
}
|
|
114
|
+
return platform.relay.handleStream(c, bot.id, connectKey);
|
|
115
|
+
});
|
|
116
|
+
// Slack API proxy
|
|
117
|
+
app.route('/', createApiProxy(platform.bots, platform.vault));
|
|
118
|
+
// Slack events
|
|
119
|
+
app.route('/', createSlackEventsHandler(platform.bots, platform.vault, platform.relay, platform.crypto));
|
|
120
|
+
// Bot installation OAuth
|
|
121
|
+
app.route('/', createOAuthHandler(platform.bots, platform.vault, platform.crypto, platform.oauthStates));
|
|
122
|
+
// Slack login setup + auth
|
|
123
|
+
app.route('/', createSetupPage(platform.workspaceAdminConfig, platform.vault));
|
|
124
|
+
app.route('/', createAuthHandler(platform.workspaceAdminConfig, platform.oauthStates, platform.crypto, platform.vault, { platformBaseUrl: config.platformBaseUrl }));
|
|
125
|
+
// Protect all subsequent web/API/admin routes.
|
|
126
|
+
app.use('/', authMiddleware.requireAuth);
|
|
127
|
+
app.use('/bots/*', authMiddleware.requireAuth);
|
|
128
|
+
app.use('/api/*', authMiddleware.requireAuth);
|
|
129
|
+
app.use('/admin/*', authMiddleware.requireAuth);
|
|
130
|
+
// Web API
|
|
131
|
+
app.route('/', createWebApi(platform.bots, provisioner, platform.crypto, config.workspaceId));
|
|
132
|
+
// Web UI pages
|
|
133
|
+
app.route('/', createPages(platform.bots, config.platformBaseUrl));
|
|
134
|
+
// Admin endpoints
|
|
135
|
+
app.get('/admin/bots', async (c) => {
|
|
136
|
+
const allBots = await platform.bots.findAllSummary();
|
|
137
|
+
return c.json({ bots: allBots });
|
|
138
|
+
});
|
|
139
|
+
app.get('/admin/connections', (c) => {
|
|
140
|
+
return c.json({
|
|
141
|
+
connected: platform.relay.connectedBots(),
|
|
142
|
+
count: platform.relay.connectedBots().length,
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
return { app, provisioner };
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { Context, Next } from 'hono';
|
|
3
|
+
import type { OAuthStateRepository, WorkspaceAdminConfigRepository } from '../types/repository.js';
|
|
4
|
+
import type { CryptoProvider } from '../types/crypto.js';
|
|
5
|
+
import type { Vault } from '../types/vault.js';
|
|
6
|
+
import { type AuthSession, type AuthSessionUser } from './session.js';
|
|
7
|
+
export interface AuthEnv {
|
|
8
|
+
Variables: {
|
|
9
|
+
user: AuthSessionUser;
|
|
10
|
+
session: AuthSession;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export declare function createAuthHandler(workspaceAdminConfig: WorkspaceAdminConfigRepository, oauthStates: OAuthStateRepository, crypto: CryptoProvider, vault: Vault, config: {
|
|
14
|
+
platformBaseUrl: string;
|
|
15
|
+
}): Hono<AuthEnv, import("hono/types").BlankSchema, "/">;
|
|
16
|
+
export declare function createAuthMiddleware(workspaceAdminConfig: WorkspaceAdminConfigRepository, vault: Vault): {
|
|
17
|
+
requireAuth: (c: Context, next: Next) => Promise<Response | undefined>;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/auth/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAGzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAA;AAClG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,cAAc,CAAA;AAqBrB,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE;QACT,IAAI,EAAE,eAAe,CAAA;QACrB,OAAO,EAAE,WAAW,CAAA;KACrB,CAAA;CACF;AAED,wBAAgB,iBAAiB,CAC/B,oBAAoB,EAAE,8BAA8B,EACpD,WAAW,EAAE,oBAAoB,EACjC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE;IACN,eAAe,EAAE,MAAM,CAAA;CACxB,wDA+JF;AAED,wBAAgB,oBAAoB,CAClC,oBAAoB,EAAE,8BAA8B,EACpD,KAAK,EAAE,KAAK;qBAEkB,OAAO,QAAQ,IAAI;EAgClD"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { deleteCookie, getCookie, setCookie } from 'hono/cookie';
|
|
3
|
+
import { AUTH_SESSION_MAX_AGE_SECONDS, createSessionCookieValue, parseSessionCookieValue, } from './session.js';
|
|
4
|
+
const DEFAULT_WORKSPACE_ADMIN_CONFIG_ID = 'default';
|
|
5
|
+
const LOGIN_STATE_PREFIX = 'login:';
|
|
6
|
+
export function createAuthHandler(workspaceAdminConfig, oauthStates, crypto, vault, config) {
|
|
7
|
+
const app = new Hono();
|
|
8
|
+
app.get('/auth/login', async (c) => {
|
|
9
|
+
const creds = await getSlackLoginCredentials(workspaceAdminConfig, vault);
|
|
10
|
+
if (!creds) {
|
|
11
|
+
return c.redirect('/setup');
|
|
12
|
+
}
|
|
13
|
+
const state = await crypto.randomHex(16);
|
|
14
|
+
const nonce = await crypto.randomHex(8);
|
|
15
|
+
await oauthStates.deleteExpired();
|
|
16
|
+
await oauthStates.create({
|
|
17
|
+
state,
|
|
18
|
+
botId: `${LOGIN_STATE_PREFIX}${nonce}`,
|
|
19
|
+
expiresAt: new Date(Date.now() + 10 * 60 * 1000),
|
|
20
|
+
});
|
|
21
|
+
const params = new URLSearchParams({
|
|
22
|
+
response_type: 'code',
|
|
23
|
+
client_id: creds.clientId,
|
|
24
|
+
scope: 'openid profile email',
|
|
25
|
+
redirect_uri: `${config.platformBaseUrl}/auth/callback`,
|
|
26
|
+
state,
|
|
27
|
+
nonce,
|
|
28
|
+
});
|
|
29
|
+
return c.redirect(`https://slack.com/openid/connect/authorize?${params.toString()}`);
|
|
30
|
+
});
|
|
31
|
+
app.get('/auth/callback', async (c) => {
|
|
32
|
+
const error = c.req.query('error');
|
|
33
|
+
if (error) {
|
|
34
|
+
return renderErrorPage(c, 'Slack 로그인 오류', error, 400);
|
|
35
|
+
}
|
|
36
|
+
const code = c.req.query('code');
|
|
37
|
+
const state = c.req.query('state');
|
|
38
|
+
if (!code || !state) {
|
|
39
|
+
return renderErrorPage(c, '잘못된 요청', 'code/state가 누락됐어요.', 400);
|
|
40
|
+
}
|
|
41
|
+
await oauthStates.deleteExpired();
|
|
42
|
+
const storedState = await oauthStates.consume(state);
|
|
43
|
+
if (!storedState || !storedState.botId.startsWith(LOGIN_STATE_PREFIX)) {
|
|
44
|
+
return renderErrorPage(c, '잘못된 상태', '로그인 상태가 만료됐거나 유효하지 않아요.', 400);
|
|
45
|
+
}
|
|
46
|
+
const creds = await getSlackLoginCredentials(workspaceAdminConfig, vault);
|
|
47
|
+
if (!creds) {
|
|
48
|
+
return c.redirect('/setup');
|
|
49
|
+
}
|
|
50
|
+
const redirectUri = `${config.platformBaseUrl}/auth/callback`;
|
|
51
|
+
const tokenRes = await fetch('https://slack.com/api/openid.connect.token', {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
54
|
+
body: new URLSearchParams({
|
|
55
|
+
client_id: creds.clientId,
|
|
56
|
+
client_secret: creds.clientSecret,
|
|
57
|
+
code,
|
|
58
|
+
redirect_uri: redirectUri,
|
|
59
|
+
grant_type: 'authorization_code',
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
62
|
+
const tokenData = (await tokenRes.json());
|
|
63
|
+
if (!tokenData.ok || !tokenData.access_token) {
|
|
64
|
+
return renderErrorPage(c, 'Slack 토큰 교환 실패', tokenData.error ?? 'unknown_error', 400);
|
|
65
|
+
}
|
|
66
|
+
const userInfoRes = await fetch('https://slack.com/api/openid.connect.userInfo', {
|
|
67
|
+
headers: { Authorization: `Bearer ${tokenData.access_token}` },
|
|
68
|
+
});
|
|
69
|
+
const userInfo = (await userInfoRes.json());
|
|
70
|
+
if (!userInfo.ok || !userInfo.sub) {
|
|
71
|
+
return renderErrorPage(c, 'Slack 사용자 정보 조회 실패', userInfo.error ?? 'unknown_error', 400);
|
|
72
|
+
}
|
|
73
|
+
const slackTeamId = userInfo['https://slack.com/team_id'] ?? '';
|
|
74
|
+
if (!slackTeamId) {
|
|
75
|
+
return renderErrorPage(c, 'Slack 팀 정보 누락', 'team_id를 확인할 수 없어요.', 400);
|
|
76
|
+
}
|
|
77
|
+
const configs = await listConfiguredSlackLoginConfigs(workspaceAdminConfig);
|
|
78
|
+
const configuredTeamIds = getConfiguredTeamIds(configs);
|
|
79
|
+
if (configuredTeamIds.length > 0 &&
|
|
80
|
+
!configuredTeamIds.includes(slackTeamId)) {
|
|
81
|
+
return renderErrorPage(c, '허용되지 않은 워크스페이스', `${slackTeamId} 워크스페이스는 이 플랫폼에 접근할 수 없어요.`, 403);
|
|
82
|
+
}
|
|
83
|
+
const defaultConfig = configs.find((cfg) => cfg.workspaceId === DEFAULT_WORKSPACE_ADMIN_CONFIG_ID);
|
|
84
|
+
const teamConfig = configs.find((cfg) => cfg.workspaceId === slackTeamId);
|
|
85
|
+
if (!teamConfig && defaultConfig) {
|
|
86
|
+
await workspaceAdminConfig.upsert({
|
|
87
|
+
workspaceId: slackTeamId,
|
|
88
|
+
slackClientId: defaultConfig.slackClientId,
|
|
89
|
+
slackClientSecretEnc: defaultConfig.slackClientSecretEnc,
|
|
90
|
+
dCookieEnc: defaultConfig.dCookieEnc,
|
|
91
|
+
xoxcTokenEnc: defaultConfig.xoxcTokenEnc,
|
|
92
|
+
workspaceDomain: defaultConfig.workspaceDomain,
|
|
93
|
+
updatedByUserId: defaultConfig.updatedByUserId,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const user = {
|
|
97
|
+
slackUserId: userInfo.sub,
|
|
98
|
+
slackTeamId,
|
|
99
|
+
name: userInfo.name ?? 'Slack User',
|
|
100
|
+
email: userInfo.email ?? null,
|
|
101
|
+
avatarUrl: userInfo.picture ?? null,
|
|
102
|
+
};
|
|
103
|
+
const expiresAt = new Date(Date.now() + AUTH_SESSION_MAX_AGE_SECONDS * 1000);
|
|
104
|
+
const sessionCookie = await createSessionCookieValue(vault, user, expiresAt);
|
|
105
|
+
setCookie(c, 'sena_session', sessionCookie, {
|
|
106
|
+
httpOnly: true,
|
|
107
|
+
secure: true,
|
|
108
|
+
sameSite: 'Lax',
|
|
109
|
+
path: '/',
|
|
110
|
+
maxAge: AUTH_SESSION_MAX_AGE_SECONDS,
|
|
111
|
+
});
|
|
112
|
+
return c.redirect('/');
|
|
113
|
+
});
|
|
114
|
+
app.post('/auth/logout', (c) => {
|
|
115
|
+
deleteCookie(c, 'sena_session', { path: '/' });
|
|
116
|
+
return c.redirect('/auth/login');
|
|
117
|
+
});
|
|
118
|
+
return app;
|
|
119
|
+
}
|
|
120
|
+
export function createAuthMiddleware(workspaceAdminConfig, vault) {
|
|
121
|
+
const requireAuth = async (c, next) => {
|
|
122
|
+
const configs = await listConfiguredSlackLoginConfigs(workspaceAdminConfig);
|
|
123
|
+
if (configs.length === 0) {
|
|
124
|
+
return unauthenticated(c, '/setup', 'slack_login_not_configured', 503);
|
|
125
|
+
}
|
|
126
|
+
const rawSession = getCookie(c, 'sena_session');
|
|
127
|
+
if (!rawSession) {
|
|
128
|
+
return unauthenticated(c, '/auth/login', 'unauthorized', 401);
|
|
129
|
+
}
|
|
130
|
+
const session = await parseSessionCookieValue(vault, rawSession);
|
|
131
|
+
if (!session) {
|
|
132
|
+
deleteCookie(c, 'sena_session', { path: '/' });
|
|
133
|
+
return unauthenticated(c, '/auth/login', 'unauthorized', 401);
|
|
134
|
+
}
|
|
135
|
+
const configuredTeamIds = getConfiguredTeamIds(configs);
|
|
136
|
+
if (configuredTeamIds.length > 0 &&
|
|
137
|
+
!configuredTeamIds.includes(session.user.slackTeamId)) {
|
|
138
|
+
deleteCookie(c, 'sena_session', { path: '/' });
|
|
139
|
+
return unauthenticated(c, '/auth/login', 'workspace_forbidden', 403);
|
|
140
|
+
}
|
|
141
|
+
c.set('user', session.user);
|
|
142
|
+
c.set('session', session);
|
|
143
|
+
await next();
|
|
144
|
+
};
|
|
145
|
+
return { requireAuth };
|
|
146
|
+
}
|
|
147
|
+
async function getSlackLoginCredentials(workspaceAdminConfig, vault) {
|
|
148
|
+
const configs = await listConfiguredSlackLoginConfigs(workspaceAdminConfig);
|
|
149
|
+
const preferredConfig = configs.find((cfg) => cfg.workspaceId !== DEFAULT_WORKSPACE_ADMIN_CONFIG_ID) ??
|
|
150
|
+
configs[0];
|
|
151
|
+
if (!preferredConfig?.slackClientId || !preferredConfig.slackClientSecretEnc) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
clientId: preferredConfig.slackClientId,
|
|
156
|
+
clientSecret: await vault.decrypt(preferredConfig.slackClientSecretEnc),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
async function listConfiguredSlackLoginConfigs(workspaceAdminConfig) {
|
|
160
|
+
const configs = await workspaceAdminConfig.findAll();
|
|
161
|
+
return configs.filter((config) => typeof config.slackClientId === 'string' &&
|
|
162
|
+
config.slackClientId.trim().length > 0 &&
|
|
163
|
+
typeof config.slackClientSecretEnc === 'string' &&
|
|
164
|
+
config.slackClientSecretEnc.length > 0);
|
|
165
|
+
}
|
|
166
|
+
function getConfiguredTeamIds(configs) {
|
|
167
|
+
return configs
|
|
168
|
+
.map((config) => config.workspaceId)
|
|
169
|
+
.filter((workspaceId) => workspaceId !== DEFAULT_WORKSPACE_ADMIN_CONFIG_ID);
|
|
170
|
+
}
|
|
171
|
+
function unauthenticated(c, redirectPath, error, status) {
|
|
172
|
+
if (c.req.path.startsWith('/api/')) {
|
|
173
|
+
return c.json({ error, redirectTo: redirectPath }, { status });
|
|
174
|
+
}
|
|
175
|
+
return c.redirect(redirectPath);
|
|
176
|
+
}
|
|
177
|
+
function renderErrorPage(c, title, message, status) {
|
|
178
|
+
return c.html(`<!DOCTYPE html>
|
|
179
|
+
<html lang="ko">
|
|
180
|
+
<head>
|
|
181
|
+
<meta charset="UTF-8">
|
|
182
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
183
|
+
<title>${escapeHtml(title)} - Sena Platform</title>
|
|
184
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
185
|
+
</head>
|
|
186
|
+
<body class="bg-gray-50 min-h-screen flex items-center justify-center px-4">
|
|
187
|
+
<main class="w-full max-w-md bg-white rounded-xl shadow-sm border border-gray-200 p-8 text-center">
|
|
188
|
+
<h1 class="text-xl font-bold text-gray-900 mb-2">${escapeHtml(title)}</h1>
|
|
189
|
+
<p class="text-sm text-gray-600 mb-6">${escapeHtml(message)}</p>
|
|
190
|
+
<a href="/auth/login" class="inline-flex items-center px-4 py-2 bg-indigo-600 text-white font-medium rounded-lg hover:bg-indigo-700 transition-colors">다시 로그인</a>
|
|
191
|
+
</main>
|
|
192
|
+
</body>
|
|
193
|
+
</html>`, { status });
|
|
194
|
+
}
|
|
195
|
+
function escapeHtml(value) {
|
|
196
|
+
return value.replace(/[&<>"']/g, (char) => {
|
|
197
|
+
switch (char) {
|
|
198
|
+
case '&':
|
|
199
|
+
return '&';
|
|
200
|
+
case '<':
|
|
201
|
+
return '<';
|
|
202
|
+
case '>':
|
|
203
|
+
return '>';
|
|
204
|
+
case '"':
|
|
205
|
+
return '"';
|
|
206
|
+
case "'":
|
|
207
|
+
return ''';
|
|
208
|
+
default:
|
|
209
|
+
return char;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/auth/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Vault } from '../types/vault.js';
|
|
2
|
+
export interface AuthSessionUser {
|
|
3
|
+
slackUserId: string;
|
|
4
|
+
slackTeamId: string;
|
|
5
|
+
name: string;
|
|
6
|
+
email: string | null;
|
|
7
|
+
avatarUrl: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface AuthSession {
|
|
10
|
+
user: AuthSessionUser;
|
|
11
|
+
expiresAt: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const AUTH_SESSION_MAX_AGE_SECONDS: number;
|
|
14
|
+
export declare function createSessionCookieValue(vault: Vault, user: AuthSessionUser, expiresAt: Date): Promise<string>;
|
|
15
|
+
export declare function parseSessionCookieValue(vault: Vault, rawCookieValue: string): Promise<AuthSession | null>;
|
|
16
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,4BAA4B,QAAoB,CAAA;AAE7D,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,IAAI,GACd,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqB7B"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const AUTH_SESSION_MAX_AGE_SECONDS = 30 * 24 * 60 * 60;
|
|
2
|
+
export async function createSessionCookieValue(vault, user, expiresAt) {
|
|
3
|
+
const encrypted = await vault.encrypt(JSON.stringify({
|
|
4
|
+
user,
|
|
5
|
+
expiresAt: expiresAt.toISOString(),
|
|
6
|
+
}));
|
|
7
|
+
return toBase64Url(encrypted);
|
|
8
|
+
}
|
|
9
|
+
export async function parseSessionCookieValue(vault, rawCookieValue) {
|
|
10
|
+
try {
|
|
11
|
+
const decrypted = await vault.decrypt(fromBase64Url(rawCookieValue));
|
|
12
|
+
const parsed = JSON.parse(decrypted);
|
|
13
|
+
if (!isAuthSession(parsed)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const expiresAt = new Date(parsed.expiresAt);
|
|
17
|
+
if (Number.isNaN(expiresAt.getTime()) || expiresAt <= new Date()) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
user: parsed.user,
|
|
22
|
+
expiresAt: expiresAt.toISOString(),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function isRecord(value) {
|
|
30
|
+
return typeof value === 'object' && value !== null;
|
|
31
|
+
}
|
|
32
|
+
function isAuthSessionUser(value) {
|
|
33
|
+
if (!isRecord(value))
|
|
34
|
+
return false;
|
|
35
|
+
return (typeof value.slackUserId === 'string' &&
|
|
36
|
+
typeof value.slackTeamId === 'string' &&
|
|
37
|
+
typeof value.name === 'string' &&
|
|
38
|
+
(value.email === null || typeof value.email === 'string') &&
|
|
39
|
+
(value.avatarUrl === null || typeof value.avatarUrl === 'string'));
|
|
40
|
+
}
|
|
41
|
+
function isAuthSession(value) {
|
|
42
|
+
if (!isRecord(value))
|
|
43
|
+
return false;
|
|
44
|
+
return typeof value.expiresAt === 'string' && isAuthSessionUser(value.user);
|
|
45
|
+
}
|
|
46
|
+
function toBase64Url(base64) {
|
|
47
|
+
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/u, '');
|
|
48
|
+
}
|
|
49
|
+
function fromBase64Url(base64Url) {
|
|
50
|
+
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
51
|
+
const paddingLength = (4 - (base64.length % 4 || 4)) % 4;
|
|
52
|
+
return base64 + '='.repeat(paddingLength);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type DrizzleD1Database } from 'drizzle-orm/d1';
|
|
2
|
+
import type { BotRepository, ConfigTokenRepository, OAuthStateRepository, WorkspaceAdminConfigRepository } from '../../types/repository.js';
|
|
3
|
+
import * as schema from './schema.js';
|
|
4
|
+
export type D1Db = DrizzleD1Database<typeof schema>;
|
|
5
|
+
export declare function initD1(d1: D1Database): D1Db;
|
|
6
|
+
export interface D1Repositories {
|
|
7
|
+
bots: BotRepository;
|
|
8
|
+
configTokens: ConfigTokenRepository;
|
|
9
|
+
oauthStates: OAuthStateRepository;
|
|
10
|
+
workspaceAdminConfig: WorkspaceAdminConfigRepository;
|
|
11
|
+
}
|
|
12
|
+
export declare function createD1Repositories(db: D1Db): D1Repositories;
|
|
13
|
+
export { bots, configTokens, oauthStates, workspaceAdminConfig } from './schema.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/db/d1/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEhE,OAAO,KAAK,EAIV,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,8BAA8B,EAC/B,MAAM,2BAA2B,CAAA;AAClC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,MAAM,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,MAAM,CAAC,CAAA;AAEnD,wBAAgB,MAAM,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CAE3C;AAqCD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAA;IACnB,YAAY,EAAE,qBAAqB,CAAA;IACnC,WAAW,EAAE,oBAAoB,CAAA;IACjC,oBAAoB,EAAE,8BAA8B,CAAA;CACrD;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,IAAI,GAAG,cAAc,CAO7D;AA2OD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA"}
|