swallowkit 1.0.0-beta.47 → 1.0.0-beta.48
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/cli/commands/add-auth.d.ts +1 -0
- package/dist/cli/commands/add-auth.d.ts.map +1 -1
- package/dist/cli/commands/add-auth.js +136 -1
- package/dist/cli/commands/add-auth.js.map +1 -1
- package/dist/cli/commands/dev.js +5 -2
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/scaffold.d.ts +9 -0
- package/dist/cli/commands/scaffold.d.ts.map +1 -1
- package/dist/cli/commands/scaffold.js +56 -12
- package/dist/cli/commands/scaffold.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/config.d.ts +7 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +81 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/mock/connector-mock-server.js +2 -2
- package/dist/core/mock/connector-mock-server.js.map +1 -1
- package/dist/core/project/manifest.js +2 -2
- package/dist/core/project/manifest.js.map +1 -1
- package/dist/core/project/validation.d.ts.map +1 -1
- package/dist/core/project/validation.js +17 -0
- package/dist/core/project/validation.js.map +1 -1
- package/dist/core/scaffold/auth-generator.d.ts +9 -2
- package/dist/core/scaffold/auth-generator.d.ts.map +1 -1
- package/dist/core/scaffold/auth-generator.js +230 -13
- package/dist/core/scaffold/auth-generator.js.map +1 -1
- package/dist/core/scaffold/connector-functions-generator.d.ts.map +1 -1
- package/dist/core/scaffold/connector-functions-generator.js +4 -2
- package/dist/core/scaffold/connector-functions-generator.js.map +1 -1
- package/dist/core/scaffold/functions-generator.d.ts.map +1 -1
- package/dist/core/scaffold/functions-generator.js +4 -2
- package/dist/core/scaffold/functions-generator.js.map +1 -1
- package/dist/core/scaffold/model-parser.d.ts.map +1 -1
- package/dist/core/scaffold/model-parser.js +8 -3
- package/dist/core/scaffold/model-parser.js.map +1 -1
- package/dist/core/scaffold/ui-generator.d.ts +3 -0
- package/dist/core/scaffold/ui-generator.d.ts.map +1 -1
- package/dist/core/scaffold/ui-generator.js +12 -8
- package/dist/core/scaffold/ui-generator.js.map +1 -1
- package/dist/types/index.d.ts +34 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/package-manager.d.ts.map +1 -1
- package/dist/utils/package-manager.js +1 -0
- package/dist/utils/package-manager.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/auth.test.ts +4 -0
- package/src/__tests__/config.test.ts +22 -1
- package/src/__tests__/mcp.test.ts +2 -2
- package/src/__tests__/multi-auth.test.ts +133 -0
- package/src/cli/commands/add-auth.ts +112 -2
- package/src/cli/commands/dev.ts +6 -3
- package/src/cli/commands/scaffold.ts +58 -14
- package/src/cli/index.ts +2 -0
- package/src/core/config.ts +69 -2
- package/src/core/mock/connector-mock-server.ts +2 -2
- package/src/core/project/manifest.ts +3 -3
- package/src/core/project/validation.ts +16 -0
- package/src/core/scaffold/auth-generator.ts +236 -14
- package/src/core/scaffold/connector-functions-generator.ts +4 -2
- package/src/core/scaffold/functions-generator.ts +4 -2
- package/src/core/scaffold/model-parser.ts +9 -3
- package/src/core/scaffold/ui-generator.ts +15 -8
- package/src/types/index.ts +35 -4
- package/src/utils/package-manager.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,cAAc,GAAG,cAAc,CAAC;AAEpE,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAGjE,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,MAAM,WAAW,iBAAiB,CAAC,OAAO;IACxC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAGD,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAGvF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAGD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,KAAK,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAGD,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAG1E,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAGD,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,GAAG,uBAAuB,CAAC;AAGrF,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,KAAK,GAAG,gBAAgB,GAAG,YAAY,GAAG,MAAM,CAAC;AAG3F,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAGD,MAAM,WAAW,aAAa;IAC5B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,eAAe,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,qGAAqG;IACrG,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,cAAc,GAAG,sBAAsB,CAmCtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAEpD;AAcD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAYrE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CACvB,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,MAAM,EAAE,GACb;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAEjC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE;IAGrE,oCAAoC;;;;;;;;;;;;EAazC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CASzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,GAAE,cAAqB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,IAAI,EAAE,cAAc,CAAC;IACrB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,sFAAsF;IACtF,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,qGAAqG;IACrG,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,cAAc,GAAG,sBAAsB,CAmCtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAEpD;AAcD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,cAAc,CAYrE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CACvB,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,MAAM,EAAE,GACb;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAEjC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE;IAGrE,oCAAoC;;;;;;;;;;;;EAazC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CASzD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,GAAE,cAAqB,GAAG,MAAM,CAMlG;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,GAAE,cAAqB,GAAG,MAAM,CAKpG;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CASjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAOzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAK/D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,cAAc,EAClB,eAAe,GAAE,eAA8B,GAC9C,MAAM,CASR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,kCAmCC;AAaD,kDAEC;AAoBD,8CAYC;AAUD,8BAKC;AAKD,gDAgBC;AAKD,wCASC;AAED,
|
|
1
|
+
{"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -443,6 +443,10 @@ describe("generateAuthImportTS", () => {
|
|
|
443
443
|
});
|
|
444
444
|
|
|
445
445
|
describe("generateAuthGuardTS", () => {
|
|
446
|
+
it("generates a named read/write policy guard", () => {
|
|
447
|
+
expect(generateAuthGuardTS({ read: "adminOnly", write: "lineUserOnly" }, "read")).toContain("requireAuth(request, \"adminOnly\")");
|
|
448
|
+
expect(generateAuthGuardTS({ policy: "adminOnly" }, "write")).toContain("requireAuth(request, \"adminOnly\")");
|
|
449
|
+
});
|
|
446
450
|
it("generates authentication-only guard for empty policy", () => {
|
|
447
451
|
const policy: ModelAuthPolicy = {};
|
|
448
452
|
const readGuard = generateAuthGuardTS(policy, "read");
|
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
import { validateConfig, loadConfigFromEnv } from "../core/config";
|
|
1
|
+
import { validateConfig, loadConfigFromEnv, normalizeAuthConfig } from "../core/config";
|
|
2
2
|
import { SwallowKitConfig } from "../types";
|
|
3
3
|
|
|
4
4
|
describe("validateConfig", () => {
|
|
5
|
+
it("normalizes a legacy provider as the default scheme", () => {
|
|
6
|
+
const auth = normalizeAuthConfig({ provider: "external-token", authorization: { defaultPolicy: "authenticated" } });
|
|
7
|
+
expect(auth?.schemes.default.provider).toBe("external-token");
|
|
8
|
+
expect(auth?.authorization.defaultPolicy).toBe("authenticated");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("accepts SWA and external token named schemes", () => {
|
|
12
|
+
const result = validateConfig({ auth: { schemes: { admin: { provider: "swa" }, lineUser: { provider: "external-token" } }, authorization: { defaultPolicy: "anonymous", policies: { adminOnly: { schemes: ["admin"] }, lineUserOnly: { schemes: ["lineUser"] } } } } });
|
|
13
|
+
expect(result).toEqual({ valid: true, errors: [] });
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("rejects undefined scheme references and ambiguous bearer schemes", () => {
|
|
17
|
+
const missing = validateConfig({ auth: { schemes: { admin: { provider: "swa" } }, authorization: { defaultPolicy: "anonymous", policies: { bad: { schemes: ["missing"] } } } } });
|
|
18
|
+
expect(missing.errors.join("\n")).toContain("auth.authorization.policies.bad.schemes");
|
|
19
|
+
const ambiguous = validateConfig({ auth: { schemes: { a: { provider: "external-token" }, b: { provider: "external-token" } }, authorization: { defaultPolicy: "anonymous", policies: { bad: { schemes: ["a", "b"] } } } } });
|
|
20
|
+
expect(ambiguous.errors.join("\n")).toContain("deterministic");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("normalizes public to anonymous", () => {
|
|
24
|
+
expect(normalizeAuthConfig({ provider: "none", authorization: { defaultPolicy: "public" } })?.authorization.defaultPolicy).toBe("anonymous");
|
|
25
|
+
});
|
|
5
26
|
it("returns valid for a complete config", () => {
|
|
6
27
|
const config: SwallowKitConfig = {
|
|
7
28
|
database: { connectionString: "AccountEndpoint=https://..." },
|
|
@@ -9,7 +9,7 @@ const itWhenBuiltEntrypointExists = fs.existsSync(builtMcpEntrypoint) ? it : it.
|
|
|
9
9
|
|
|
10
10
|
describe("SwallowKit MCP tool definitions", () => {
|
|
11
11
|
it("delegates inspect_project to the machine CLI", async () => {
|
|
12
|
-
const runner = jest.fn(async (
|
|
12
|
+
const runner = jest.fn(async () => ({
|
|
13
13
|
stdout: JSON.stringify({
|
|
14
14
|
ok: true,
|
|
15
15
|
command: "inspect-project",
|
|
@@ -48,7 +48,7 @@ describe("SwallowKit MCP tool definitions", () => {
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
it("delegates scaffold_model with explicit args", async () => {
|
|
51
|
-
const runner = jest.fn(async (
|
|
51
|
+
const runner = jest.fn(async () => ({
|
|
52
52
|
stdout: JSON.stringify({
|
|
53
53
|
ok: true,
|
|
54
54
|
command: "generate-scaffold",
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as os from "os";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { addAuthCommand } from "../cli/commands/add-auth";
|
|
5
|
+
import {
|
|
6
|
+
generateBFFCallFunctionWithMultipleAuth,
|
|
7
|
+
generateNamedAuthRouterCSharp,
|
|
8
|
+
generateNamedAuthRouterPython,
|
|
9
|
+
generateNamedAuthRouterTS,
|
|
10
|
+
} from "../core/scaffold/auth-generator";
|
|
11
|
+
import { normalizeAuthConfig } from "../core/config";
|
|
12
|
+
import { parseAuthPolicy } from "../core/scaffold/model-parser";
|
|
13
|
+
import { createBasicModelInfo } from "./fixtures";
|
|
14
|
+
import { generateCSharpAzureFunctionsCRUD, generateCompactAzureFunctionsCRUD, generatePythonAzureFunctionsCRUD } from "../core/scaffold/functions-generator";
|
|
15
|
+
|
|
16
|
+
const auth = normalizeAuthConfig({
|
|
17
|
+
schemes: {
|
|
18
|
+
admin: { provider: "swa" },
|
|
19
|
+
lineUser: { provider: "external-token" },
|
|
20
|
+
},
|
|
21
|
+
authorization: {
|
|
22
|
+
defaultPolicy: "anonymous",
|
|
23
|
+
policies: {
|
|
24
|
+
adminOnly: { schemes: ["admin"], roles: ["authenticated"] },
|
|
25
|
+
lineUserOnly: { schemes: ["lineUser"], roles: ["authenticated"] },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
})!;
|
|
29
|
+
|
|
30
|
+
describe("named authentication routers", () => {
|
|
31
|
+
it("generates deterministic TypeScript policy routing and normalized principals", () => {
|
|
32
|
+
const code = generateNamedAuthRouterTS(auth);
|
|
33
|
+
expect(code).toContain("policy.schemes.filter");
|
|
34
|
+
expect(code).toContain("candidates.length !== 1");
|
|
35
|
+
expect(code).toContain("subject: value.userId");
|
|
36
|
+
expect(code).toContain("scheme + ':' + principal.subject");
|
|
37
|
+
expect(code).toContain("new AuthError(403");
|
|
38
|
+
expect(code).toContain("new AuthError(503");
|
|
39
|
+
expect(code).not.toContain("JWT_SECRET");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("generates equivalent C# and Python named guards", () => {
|
|
43
|
+
const csharp = generateNamedAuthRouterCSharp(auth);
|
|
44
|
+
const python = generateNamedAuthRouterPython(auth);
|
|
45
|
+
expect(csharp).toContain("record AuthPrincipal(string Subject, string Scheme, string Issuer");
|
|
46
|
+
expect(csharp).toContain("candidates.Length != 1");
|
|
47
|
+
expect(csharp).toContain("HttpStatusCode.Forbidden");
|
|
48
|
+
expect(python).toContain('principal["scheme"] + ":" + principal["subject"]');
|
|
49
|
+
expect(python).toContain("len(candidates) != 1");
|
|
50
|
+
expect(python).toContain("AuthError(503");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("generates valid branch structure for an SWA-only Python router", () => {
|
|
54
|
+
const swaOnly = normalizeAuthConfig({ schemes: { admin: { provider: "swa", swa: { allowedProviders: ["github"] } } }, authorization: { defaultPolicy: "anonymous", policies: { adminOnly: { schemes: ["admin"] } } } })!;
|
|
55
|
+
const python = generateNamedAuthRouterPython(swaOnly);
|
|
56
|
+
expect(python).toContain(' if PROVIDERS[scheme] == "swa":');
|
|
57
|
+
expect(python).not.toContain(' elif PROVIDERS[scheme] == "swa":');
|
|
58
|
+
expect(python).toContain("ALLOWED_PROVIDERS");
|
|
59
|
+
expect(generateNamedAuthRouterCSharp(swaOnly)).toContain("AllowedProviders[scheme]");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("scaffolds named read/write guards for all Functions languages", () => {
|
|
63
|
+
const policy = { read: "adminOnly", write: "lineUserOnly" };
|
|
64
|
+
const model = createBasicModelInfo();
|
|
65
|
+
const ts = generateCompactAzureFunctionsCRUD(model, "@fixture/shared", policy);
|
|
66
|
+
const cs = generateCSharpAzureFunctionsCRUD(model, policy);
|
|
67
|
+
const py = generatePythonAzureFunctionsCRUD(model, policy).blueprint;
|
|
68
|
+
expect(ts).toContain("./auth/auth-router");
|
|
69
|
+
expect(ts).toContain('requireAuth(request, "adminOnly")');
|
|
70
|
+
expect(ts).toContain('requireAuth(request, "lineUserOnly")');
|
|
71
|
+
expect(cs).toContain('AuthRouter.Authorize(request, "adminOnly")');
|
|
72
|
+
expect(cs).toContain('AuthRouter.Authorize(request, "lineUserOnly")');
|
|
73
|
+
expect(py).toContain("from auth.auth_router import");
|
|
74
|
+
expect(py).toContain('require_auth(req, "adminOnly")');
|
|
75
|
+
expect(py).toContain('require_auth(req, "lineUserOnly")');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("forwards both credential sources and the Functions host key", () => {
|
|
79
|
+
const code = generateBFFCallFunctionWithMultipleAuth();
|
|
80
|
+
expect(code).toContain("fetchHeaders['Authorization']");
|
|
81
|
+
expect(code).toContain("fetchHeaders['x-ms-client-principal']");
|
|
82
|
+
expect(code).toContain("'x-functions-key'");
|
|
83
|
+
expect(code).not.toMatch(/console\.log\([^\n]*(authorization|principal|cookie)/i);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("parses model-wide and operation-specific named policies", () => {
|
|
87
|
+
expect(parseAuthPolicy("export const authPolicy = { policy: 'adminOnly' };"))
|
|
88
|
+
.toEqual({ policy: "adminOnly" });
|
|
89
|
+
expect(parseAuthPolicy("export const authPolicy = { read: 'adminOnly', write: 'lineUserOnly' };"))
|
|
90
|
+
.toEqual({ read: "adminOnly", write: "lineUserOnly" });
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe("add-auth named scheme CLI", () => {
|
|
95
|
+
const originalCwd = process.cwd();
|
|
96
|
+
let root: string;
|
|
97
|
+
|
|
98
|
+
beforeEach(() => {
|
|
99
|
+
root = fs.mkdtempSync(path.join(os.tmpdir(), "swallowkit-multi-auth-"));
|
|
100
|
+
fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "fixture" }));
|
|
101
|
+
fs.writeFileSync(path.join(root, "swallowkit.config.json"), JSON.stringify({ backend: { language: "typescript" }, auth: { schemes: {}, authorization: { defaultPolicy: "anonymous", policies: {} } } }, null, 2));
|
|
102
|
+
process.chdir(root);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
afterEach(() => {
|
|
106
|
+
process.chdir(originalCwd);
|
|
107
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("adds two schemes without overwriting the first verifier", async () => {
|
|
111
|
+
await addAuthCommand({ scheme: "admin", provider: "swa" });
|
|
112
|
+
await addAuthCommand({ scheme: "lineUser", provider: "external-token" });
|
|
113
|
+
const verifier = path.join(root, "functions", "src", "auth", "schemes", "line-user", "verifier.ts");
|
|
114
|
+
fs.writeFileSync(verifier, "// user verifier\n", "utf-8");
|
|
115
|
+
const config = JSON.parse(fs.readFileSync(path.join(root, "swallowkit.config.json"), "utf-8"));
|
|
116
|
+
expect(config.auth.schemes.admin.provider).toBe("swa");
|
|
117
|
+
expect(config.auth.schemes.lineUser.provider).toBe("external-token");
|
|
118
|
+
await expect(addAuthCommand({ scheme: "lineUser", provider: "external-token" })).rejects.toThrow("already exists");
|
|
119
|
+
expect(fs.readFileSync(verifier, "utf-8")).toBe("// user verifier\n");
|
|
120
|
+
expect(fs.readFileSync(path.join(root, "lib", "api", "call-function.ts"), "utf-8")).toContain("x-functions-key");
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("updates a JavaScript config that already has a trailing comma", async () => {
|
|
124
|
+
fs.rmSync(path.join(root, "swallowkit.config.json"));
|
|
125
|
+
fs.writeFileSync(path.join(root, "swallowkit.config.js"), "module.exports = {\n backend: { language: 'typescript' },\n api: { endpoint: '/api/test' },\n};\n");
|
|
126
|
+
await addAuthCommand({ scheme: "admin", provider: "swa" });
|
|
127
|
+
const content = fs.readFileSync(path.join(root, "swallowkit.config.js"), "utf-8");
|
|
128
|
+
expect(content).not.toContain(",,");
|
|
129
|
+
const configModule = { exports: {} as Record<string, unknown> };
|
|
130
|
+
new Function("module", content)(configModule);
|
|
131
|
+
expect((configModule.exports as { auth: { schemes: { admin: { provider: string } } } }).auth.schemes.admin.provider).toBe("swa");
|
|
132
|
+
});
|
|
133
|
+
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import * as fs from "fs";
|
|
7
7
|
import * as path from "path";
|
|
8
|
-
import { ensureSwallowKitProject, getBackendLanguage, getConnectorDefinition,
|
|
8
|
+
import { ensureSwallowKitProject, getBackendLanguage, getConnectorDefinition, getValidatedFullConfig } from "../../core/config";
|
|
9
9
|
import { AuthProvider, BackendLanguage, CustomJwtConfig, RdbConnectorConfig } from "../../types";
|
|
10
10
|
import {
|
|
11
11
|
generateAuthModels,
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
generateAuthContext,
|
|
24
24
|
generateBFFCallFunctionWithAuth,
|
|
25
25
|
generateBFFCallFunctionWithSwaAuth,
|
|
26
|
+
generateBFFCallFunctionWithMultipleAuth,
|
|
26
27
|
generateSwaAuthHelperTS,
|
|
27
28
|
generateSwaAuthHelperCSharp,
|
|
28
29
|
generateSwaAuthHelperPython,
|
|
@@ -39,12 +40,15 @@ import {
|
|
|
39
40
|
generateExternalTokenVerifierPython,
|
|
40
41
|
generateExternalTokenHelperPython,
|
|
41
42
|
generateExternalAuthMePython,
|
|
43
|
+
generateNamedExternalTokenVerifierCSharp,
|
|
44
|
+
generateNamedExternalTokenVerifierPython,
|
|
42
45
|
} from "../../core/scaffold/auth-generator";
|
|
43
46
|
import { syncProjectManifest } from "../../core/project/manifest";
|
|
44
47
|
import { buildSharedTsConfig } from "./init";
|
|
45
48
|
|
|
46
49
|
interface AddAuthOptions {
|
|
47
50
|
provider?: string;
|
|
51
|
+
scheme?: string;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
function writeIfMissing(filePath: string, content: string): void {
|
|
@@ -239,9 +243,18 @@ export async function addAuthCommand(options: AddAuthOptions) {
|
|
|
239
243
|
}
|
|
240
244
|
|
|
241
245
|
const backendLanguage = getBackendLanguage();
|
|
242
|
-
const config =
|
|
246
|
+
const config = getValidatedFullConfig();
|
|
243
247
|
const cwd = process.cwd();
|
|
244
248
|
|
|
249
|
+
if (options.scheme) {
|
|
250
|
+
if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(options.scheme)) throw new Error("--scheme must start with a letter and contain only letters, digits, '_' or '-'");
|
|
251
|
+
if (provider === "none" || provider === "swa-custom") throw new Error(`Provider '${provider}' cannot be added as a named scheme`);
|
|
252
|
+
addNamedScheme(cwd, options.scheme, provider, backendLanguage);
|
|
253
|
+
await syncProjectManifest();
|
|
254
|
+
console.log(`\n Named authentication scheme '${options.scheme}' added.`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
245
258
|
if (provider === "swa-custom") {
|
|
246
259
|
throw new Error("The swa-custom provider is not implemented. Use --provider swa or --provider custom-jwt.");
|
|
247
260
|
}
|
|
@@ -364,6 +377,103 @@ export async function addAuthCommand(options: AddAuthOptions) {
|
|
|
364
377
|
console.log(` 5. Run scaffold to regenerate functions with auth guards`);
|
|
365
378
|
}
|
|
366
379
|
|
|
380
|
+
function findObjectEnd(content: string, open: number): number {
|
|
381
|
+
let depth = 0, quote = "";
|
|
382
|
+
for (let i = open; i < content.length; i++) {
|
|
383
|
+
const ch = content[i];
|
|
384
|
+
if (quote) { if (ch === quote && content[i - 1] !== "\\") quote = ""; continue; }
|
|
385
|
+
if (ch === "'" || ch === '"' || ch === "`") { quote = ch; continue; }
|
|
386
|
+
if (ch === "{") depth++;
|
|
387
|
+
if (ch === "}" && --depth === 0) return i;
|
|
388
|
+
}
|
|
389
|
+
return -1;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function updateConfigWithNamedScheme(cwd: string, scheme: string, provider: AuthProvider): void {
|
|
393
|
+
const jsPath = path.join(cwd, "swallowkit.config.js");
|
|
394
|
+
const jsonPath = path.join(cwd, "swallowkit.config.json");
|
|
395
|
+
const configPath = fs.existsSync(jsPath) ? jsPath : jsonPath;
|
|
396
|
+
if (!fs.existsSync(configPath)) throw new Error("swallowkit.config.js or swallowkit.config.json is required");
|
|
397
|
+
if (configPath.endsWith(".json")) {
|
|
398
|
+
const value = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
399
|
+
value.auth ??= {};
|
|
400
|
+
value.auth.schemes ??= {};
|
|
401
|
+
if (value.auth.schemes[scheme]) throw new Error(`auth.schemes.${scheme} already exists; no files were changed`);
|
|
402
|
+
value.auth.schemes[scheme] = provider === "custom-jwt" ? { provider, customJwt: defaultCustomJwtConfig() } : { provider };
|
|
403
|
+
value.auth.authorization ??= { defaultPolicy: "anonymous", policies: {} };
|
|
404
|
+
fs.writeFileSync(configPath, JSON.stringify(value, null, 2) + "\n", "utf-8");
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
let content = fs.readFileSync(configPath, "utf-8");
|
|
408
|
+
const authMatch = /\bauth\s*:\s*\{/.exec(content);
|
|
409
|
+
const customJwt = defaultCustomJwtConfig();
|
|
410
|
+
const entry = provider === "custom-jwt"
|
|
411
|
+
? `\n ${scheme}: { provider: 'custom-jwt', customJwt: ${JSON.stringify(customJwt)} },`
|
|
412
|
+
: `\n ${scheme}: { provider: '${provider}' },`;
|
|
413
|
+
if (!authMatch) {
|
|
414
|
+
const rootEnd = content.lastIndexOf("}");
|
|
415
|
+
const beforeRootEnd = content.slice(0, rootEnd).trimEnd();
|
|
416
|
+
const separator = beforeRootEnd.endsWith(",") || beforeRootEnd.endsWith("{") ? "" : ",";
|
|
417
|
+
content = `${beforeRootEnd}${separator}\n auth: {\n schemes: {${entry}\n },\n authorization: { defaultPolicy: 'anonymous', policies: {} },\n },\n${content.slice(rootEnd)}`;
|
|
418
|
+
} else {
|
|
419
|
+
const authOpen = content.indexOf("{", authMatch.index);
|
|
420
|
+
const authEnd = findObjectEnd(content, authOpen);
|
|
421
|
+
const authBody = content.slice(authOpen + 1, authEnd);
|
|
422
|
+
const schemesMatch = /\bschemes\s*:\s*\{/.exec(authBody);
|
|
423
|
+
if (schemesMatch) {
|
|
424
|
+
const schemesOpen = authOpen + 1 + authBody.indexOf("{", schemesMatch.index);
|
|
425
|
+
const schemesEnd = findObjectEnd(content, schemesOpen);
|
|
426
|
+
const existing = content.slice(schemesOpen + 1, schemesEnd);
|
|
427
|
+
if (new RegExp(`(^|[,\\s])${scheme}\\s*:`).test(existing)) throw new Error(`auth.schemes.${scheme} already exists; no files were changed`);
|
|
428
|
+
content = content.slice(0, schemesEnd) + entry + "\n " + content.slice(schemesEnd);
|
|
429
|
+
} else {
|
|
430
|
+
content = content.slice(0, authOpen + 1) + `\n schemes: {${entry}\n },` + content.slice(authOpen + 1);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
fs.writeFileSync(configPath, content, "utf-8");
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function addNamedScheme(cwd: string, scheme: string, provider: AuthProvider, language: BackendLanguage): void {
|
|
437
|
+
// Validate/update config before creating files, so duplicate names stop safely.
|
|
438
|
+
updateConfigWithNamedScheme(cwd, scheme, provider);
|
|
439
|
+
const slug = scheme.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/_/g, "-").toLowerCase();
|
|
440
|
+
if (language === "typescript") {
|
|
441
|
+
const dir = path.join(cwd, "functions", "src", "auth", "schemes", slug);
|
|
442
|
+
if (provider === "external-token") writeIfMissing(path.join(dir, "verifier.ts"), generateExternalTokenVerifierTS());
|
|
443
|
+
else if (provider === "swa") writeIfMissing(path.join(dir, "adapter.ts"), generateSwaAuthHelperTS());
|
|
444
|
+
else writeIfMissing(path.join(dir, "jwt-helper.ts"), generateJwtHelperTS());
|
|
445
|
+
} else if (language === "csharp") {
|
|
446
|
+
const dir = path.join(cwd, "functions", "Auth", "Schemes", slug);
|
|
447
|
+
if (provider === "external-token") writeIfMissing(path.join(dir, "ExternalTokenVerifier.cs"), generateNamedExternalTokenVerifierCSharp(scheme));
|
|
448
|
+
else if (provider === "swa") writeIfMissing(path.join(dir, "SwaAdapter.cs"), generateSwaAuthHelperCSharp());
|
|
449
|
+
else writeIfMissing(path.join(dir, "JwtHelper.cs"), generateJwtHelperCSharp());
|
|
450
|
+
} else {
|
|
451
|
+
const dir = path.join(cwd, "functions", "auth", "schemes", slug.replace(/-/g, "_"));
|
|
452
|
+
if (provider === "external-token") writeIfMissing(path.join(dir, "verifier.py"), generateNamedExternalTokenVerifierPython(scheme));
|
|
453
|
+
else if (provider === "swa") writeIfMissing(path.join(dir, "adapter.py"), generateSwaAuthHelperPython());
|
|
454
|
+
else writeIfMissing(path.join(dir, "jwt_helper.py"), generateJwtHelperPython());
|
|
455
|
+
}
|
|
456
|
+
const clientDir = path.join(cwd, "lib", "auth", "schemes", slug);
|
|
457
|
+
if (provider === "external-token") {
|
|
458
|
+
writeIfMissing(path.join(clientDir, "token-adapter.ts"), generateExternalTokenAdapter());
|
|
459
|
+
writeIfMissing(path.join(clientDir, "authenticated-fetch.ts"), generateAuthenticatedFetch().replace("'./external-token-adapter'", "'./token-adapter'"));
|
|
460
|
+
writeIfMissing(path.join(clientDir, "auth-context.tsx"), generateExternalTokenAuthContext().replace(/external-token-adapter/g, "token-adapter"));
|
|
461
|
+
} else if (provider === "swa") {
|
|
462
|
+
writeIfMissing(path.join(clientDir, "auth-context.tsx"), generateSwaAuthContext());
|
|
463
|
+
} else if (provider === "custom-jwt") {
|
|
464
|
+
writeIfMissing(path.join(clientDir, "auth-context.tsx"), generateAuthContext());
|
|
465
|
+
}
|
|
466
|
+
const callFunctionPath = path.join(cwd, "lib", "api", "call-function.ts");
|
|
467
|
+
if (!fs.existsSync(callFunctionPath)) writeIfMissing(callFunctionPath, generateBFFCallFunctionWithMultipleAuth());
|
|
468
|
+
else {
|
|
469
|
+
const current = fs.readFileSync(callFunctionPath, "utf-8");
|
|
470
|
+
if (!current.includes("x-ms-client-principal") || !current.includes("fetchHeaders['Authorization']")) {
|
|
471
|
+
if (current.includes("SwallowKit BFF Call Function Helper")) fs.writeFileSync(callFunctionPath, generateBFFCallFunctionWithMultipleAuth(), "utf-8");
|
|
472
|
+
else console.warn(" Existing customized lib/api/call-function.ts was preserved. Ensure it forwards Bearer and SWA credentials without logging them.");
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
367
477
|
/**
|
|
368
478
|
* Ensure the shared package has proper build infrastructure
|
|
369
479
|
* (tsconfig.json, build script, typescript devDependency).
|
package/src/cli/commands/dev.ts
CHANGED
|
@@ -7,7 +7,7 @@ import * as fs from 'fs';
|
|
|
7
7
|
import * as os from 'os';
|
|
8
8
|
import * as net from 'net';
|
|
9
9
|
import { CosmosClient, PartitionKeyKind } from '@azure/cosmos';
|
|
10
|
-
import { ensureSwallowKitProject, getBackendLanguage, getAuthConfig } from '../../core/config';
|
|
10
|
+
import { ensureSwallowKitProject, getBackendLanguage, getAuthConfig, normalizeAuthConfig } from '../../core/config';
|
|
11
11
|
import { ModelInfo } from '../../core/scaffold/model-parser';
|
|
12
12
|
import {
|
|
13
13
|
applyDevSeedEnvironment,
|
|
@@ -648,7 +648,8 @@ async function startDevEnvironment(options: DevOptions) {
|
|
|
648
648
|
const pmCmd = getCommands(pm);
|
|
649
649
|
const backendLanguage = getBackendLanguage();
|
|
650
650
|
const authConfig = getAuthConfig();
|
|
651
|
-
const
|
|
651
|
+
const normalizedAuth = normalizeAuthConfig(authConfig);
|
|
652
|
+
const useSwaEmulator = Boolean(normalizedAuth && Object.values(normalizedAuth.schemes).some(scheme => scheme.provider === 'swa')) && !options.noSwa;
|
|
652
653
|
const swaCommand = useSwaEmulator ? await resolveSwaCliCommand(process.cwd()) : null;
|
|
653
654
|
|
|
654
655
|
if (useSwaEmulator && !swaCommand) {
|
|
@@ -981,7 +982,9 @@ async function startDevEnvironment(options: DevOptions) {
|
|
|
981
982
|
passwordHashColumn: authConfig.customJwt.passwordHashColumn,
|
|
982
983
|
rolesColumn: authConfig.customJwt.rolesColumn,
|
|
983
984
|
},
|
|
984
|
-
defaultPolicy: authConfig.authorization?.defaultPolicy
|
|
985
|
+
defaultPolicy: authConfig.authorization?.defaultPolicy === "public" ? "anonymous" :
|
|
986
|
+
authConfig.authorization?.defaultPolicy === "authenticated" || authConfig.authorization?.defaultPolicy === "anonymous"
|
|
987
|
+
? authConfig.authorization.defaultPolicy : undefined,
|
|
985
988
|
};
|
|
986
989
|
}
|
|
987
990
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import * as fs from "fs";
|
|
7
7
|
import * as path from "path";
|
|
8
8
|
import { spawnSync } from "child_process";
|
|
9
|
-
import { getBackendLanguage, getConnectorDefinition, getAuthConfig, ensureSwallowKitProject } from "../../core/config";
|
|
9
|
+
import { getBackendLanguage, getConnectorDefinition, getAuthConfig, getFullConfig, getNormalizedAuthConfig, ensureSwallowKitProject, normalizeAuthConfig, validateConfig } from "../../core/config";
|
|
10
10
|
import { ModelInfo, parseModelFile, toKebabCase, toPascalCase, toCamelCase } from "../../core/scaffold/model-parser";
|
|
11
11
|
import {
|
|
12
12
|
generateCSharpAzureFunctionsCRUD,
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
AuthConfig,
|
|
43
43
|
} from "../../types";
|
|
44
44
|
import { syncProjectManifest } from "../../core/project/manifest";
|
|
45
|
+
import { generateBFFCallFunctionWithAuth, generateBFFCallFunctionWithMultipleAuth, generateBFFCallFunctionWithSwaAuth, generateNamedAuthRouterCSharp, generateNamedAuthRouterPython, generateNamedAuthRouterTS } from "../../core/scaffold/auth-generator";
|
|
45
46
|
|
|
46
47
|
interface ScaffoldOptions {
|
|
47
48
|
model: string; // モデルファイルのパス(例: "lib/models/todo.ts" or "todo")
|
|
@@ -74,6 +75,9 @@ export async function scaffoldCommand(options: ScaffoldOptions) {
|
|
|
74
75
|
// SwallowKit プロジェクトディレクトリかどうかを検証
|
|
75
76
|
ensureSwallowKitProject("scaffold");
|
|
76
77
|
|
|
78
|
+
const configValidation = validateConfig(getFullConfig());
|
|
79
|
+
if (!configValidation.valid) throw new Error(`Invalid SwallowKit configuration:\n${configValidation.errors.map(error => `- ${error}`).join("\n")}`);
|
|
80
|
+
|
|
77
81
|
console.log("🏗️ SwallowKit Scaffold: Generating CRUD operations...\n");
|
|
78
82
|
|
|
79
83
|
try {
|
|
@@ -159,11 +163,11 @@ export async function scaffoldCommand(options: ScaffoldOptions) {
|
|
|
159
163
|
const uiAuthPolicy = resolveAuthPolicy(modelInfo, uiAuthConfig);
|
|
160
164
|
const uiAuthOptions: UIAuthOptions | undefined =
|
|
161
165
|
uiAuthPolicy && uiAuthConfig && uiAuthConfig.provider !== 'none'
|
|
162
|
-
?
|
|
166
|
+
? createUIAuthOptions(uiAuthPolicy, uiAuthConfig)
|
|
163
167
|
: undefined;
|
|
164
168
|
await generateUIComponents(modelInfo, sharedPackageName, uiAuthOptions);
|
|
165
|
-
if (
|
|
166
|
-
applyExternalTokenFetchToGeneratedUi(modelInfo);
|
|
169
|
+
if (uiAuthOptions?.authenticatedFetchImport) {
|
|
170
|
+
applyExternalTokenFetchToGeneratedUi(modelInfo, uiAuthOptions.authenticatedFetchImport);
|
|
167
171
|
}
|
|
168
172
|
await updateNavigationMenu(modelInfo);
|
|
169
173
|
}
|
|
@@ -193,7 +197,7 @@ export async function scaffoldCommand(options: ScaffoldOptions) {
|
|
|
193
197
|
}
|
|
194
198
|
}
|
|
195
199
|
|
|
196
|
-
function applyExternalTokenFetchToGeneratedUi(modelInfo: ModelInfo): void {
|
|
200
|
+
function applyExternalTokenFetchToGeneratedUi(modelInfo: ModelInfo, importPath = '@/lib/auth/authenticated-fetch'): void {
|
|
197
201
|
const uiRoot = path.join(process.cwd(), 'app', toKebabCase(modelInfo.name));
|
|
198
202
|
if (!fs.existsSync(uiRoot)) return;
|
|
199
203
|
const visit = (dir: string): void => {
|
|
@@ -208,9 +212,9 @@ function applyExternalTokenFetchToGeneratedUi(modelInfo: ModelInfo): void {
|
|
|
208
212
|
/(if \(!res\.ok\) throw new Error\([^\n]+\);)/g,
|
|
209
213
|
`if (res.status === 401) throw new Error('Authentication required');\n $1`
|
|
210
214
|
);
|
|
211
|
-
if (!content.includes(
|
|
215
|
+
if (!content.includes(importPath)) {
|
|
212
216
|
const directive = content.match(/^'use client';\s*\r?\n/)?.[0] ?? '';
|
|
213
|
-
content = `${directive}import { authenticatedFetch } from '
|
|
217
|
+
content = `${directive}import { authenticatedFetch } from '${importPath}';\n${content.slice(directive.length)}`;
|
|
214
218
|
}
|
|
215
219
|
fs.writeFileSync(target, content, 'utf-8');
|
|
216
220
|
}
|
|
@@ -224,9 +228,13 @@ function applyExternalTokenFetchToGeneratedUi(modelInfo: ModelInfo): void {
|
|
|
224
228
|
* - なければ auth.authorization.defaultPolicy に従う
|
|
225
229
|
* - auth 設定がなければ undefined(ガードなし)
|
|
226
230
|
*/
|
|
227
|
-
function resolveAuthPolicy(modelInfo: ModelInfo, authConfig: AuthConfig | undefined): ModelAuthPolicy | undefined {
|
|
231
|
+
export function resolveAuthPolicy(modelInfo: ModelInfo, authConfig: AuthConfig | undefined): ModelAuthPolicy | undefined {
|
|
228
232
|
// モデルに明示的な authPolicy がある場合はそれを使用
|
|
229
233
|
if (modelInfo.authPolicy) {
|
|
234
|
+
const normalized = normalizeAuthConfig(authConfig);
|
|
235
|
+
for (const policyName of [modelInfo.authPolicy.policy, typeof modelInfo.authPolicy.read === 'string' ? modelInfo.authPolicy.read : undefined, typeof modelInfo.authPolicy.write === 'string' ? modelInfo.authPolicy.write : undefined].filter((value): value is string => Boolean(value))) {
|
|
236
|
+
if (!normalized?.authorization.policies[policyName]) throw new Error(`Model '${modelInfo.name}' references undefined auth policy '${policyName}'. Define auth.authorization.policies.${policyName}.`);
|
|
237
|
+
}
|
|
230
238
|
return modelInfo.authPolicy;
|
|
231
239
|
}
|
|
232
240
|
|
|
@@ -236,11 +244,13 @@ function resolveAuthPolicy(modelInfo: ModelInfo, authConfig: AuthConfig | undefi
|
|
|
236
244
|
}
|
|
237
245
|
|
|
238
246
|
// defaultPolicy が 'authenticated' なら認証のみ(ロール指定なし)のポリシーを返す
|
|
239
|
-
const defaultPolicy = authConfig.authorization?.defaultPolicy ?? 'authenticated';
|
|
247
|
+
const defaultPolicy = authConfig.authorization?.defaultPolicy === 'public' ? 'anonymous' : authConfig.authorization?.defaultPolicy ?? 'authenticated';
|
|
240
248
|
if (defaultPolicy === 'authenticated') {
|
|
241
249
|
return {}; // 空のポリシー = 認証のみ、ロール制限なし
|
|
242
250
|
}
|
|
243
251
|
|
|
252
|
+
if (defaultPolicy !== 'anonymous') return { policy: defaultPolicy };
|
|
253
|
+
|
|
244
254
|
// defaultPolicy が 'anonymous' なら認証不要
|
|
245
255
|
return undefined;
|
|
246
256
|
}
|
|
@@ -330,13 +340,14 @@ async function generateCallFunctionHelper(): Promise<void> {
|
|
|
330
340
|
|
|
331
341
|
// auth 設定がある場合は Authorization ヘッダー転送版を生成
|
|
332
342
|
const authConfig = getAuthConfig();
|
|
333
|
-
const
|
|
343
|
+
const normalizedAuth = normalizeAuthConfig(authConfig);
|
|
344
|
+
const hasAuth = Boolean(normalizedAuth && Object.keys(normalizedAuth.schemes).length > 0);
|
|
334
345
|
let helperCode: string;
|
|
335
346
|
if (hasAuth) {
|
|
336
|
-
const
|
|
337
|
-
helperCode =
|
|
338
|
-
? generateBFFCallFunctionWithSwaAuth()
|
|
339
|
-
: generateBFFCallFunctionWithAuth();
|
|
347
|
+
const providers = new Set(Object.values(normalizedAuth!.schemes).map(scheme => scheme.provider));
|
|
348
|
+
helperCode = normalizedAuth!.schemes.default && Object.keys(normalizedAuth!.schemes).length === 1
|
|
349
|
+
? authConfig?.provider === "swa" ? generateBFFCallFunctionWithSwaAuth() : generateBFFCallFunctionWithAuth()
|
|
350
|
+
: providers.has("swa") ? generateBFFCallFunctionWithMultipleAuth() : generateBFFCallFunctionWithAuth();
|
|
340
351
|
} else {
|
|
341
352
|
helperCode = generateBFFCallFunction();
|
|
342
353
|
}
|
|
@@ -365,6 +376,12 @@ async function generateFunctionsCode(
|
|
|
365
376
|
|
|
366
377
|
const modelKebab = toKebabCase(modelInfo.name);
|
|
367
378
|
if (backendLanguage === "typescript") {
|
|
379
|
+
const normalizedAuth = getNormalizedAuthConfig();
|
|
380
|
+
if (normalizedAuth && Object.keys(normalizedAuth.schemes).some(name => name !== "default")) {
|
|
381
|
+
const routerPath = path.join(process.cwd(), functionsDir, "src", "auth", "auth-router.ts");
|
|
382
|
+
fs.mkdirSync(path.dirname(routerPath), { recursive: true });
|
|
383
|
+
fs.writeFileSync(routerPath, generateNamedAuthRouterTS(normalizedAuth), "utf-8");
|
|
384
|
+
}
|
|
368
385
|
const functionFilePath = path.join(
|
|
369
386
|
process.cwd(),
|
|
370
387
|
functionsDir,
|
|
@@ -384,6 +401,12 @@ async function generateFunctionsCode(
|
|
|
384
401
|
}
|
|
385
402
|
|
|
386
403
|
if (backendLanguage === "csharp") {
|
|
404
|
+
const normalizedAuth = getNormalizedAuthConfig();
|
|
405
|
+
if (normalizedAuth && Object.keys(normalizedAuth.schemes).some(name => name !== "default")) {
|
|
406
|
+
const routerPath = path.join(process.cwd(), functionsDir, "Auth", "AuthRouter.cs");
|
|
407
|
+
fs.mkdirSync(path.dirname(routerPath), { recursive: true });
|
|
408
|
+
fs.writeFileSync(routerPath, generateNamedAuthRouterCSharp(normalizedAuth), "utf-8");
|
|
409
|
+
}
|
|
387
410
|
const crudDir = path.join(process.cwd(), functionsDir, "Crud");
|
|
388
411
|
const functionFilePath = path.join(crudDir, `${modelInfo.name}CrudFunctions.cs`);
|
|
389
412
|
fs.mkdirSync(crudDir, { recursive: true });
|
|
@@ -400,6 +423,13 @@ async function generateFunctionsCode(
|
|
|
400
423
|
return;
|
|
401
424
|
}
|
|
402
425
|
|
|
426
|
+
const normalizedAuth = getNormalizedAuthConfig();
|
|
427
|
+
if (normalizedAuth && Object.keys(normalizedAuth.schemes).some(name => name !== "default")) {
|
|
428
|
+
const routerPath = path.join(process.cwd(), functionsDir, "auth", "auth_router.py");
|
|
429
|
+
fs.mkdirSync(path.dirname(routerPath), { recursive: true });
|
|
430
|
+
fs.writeFileSync(routerPath, generateNamedAuthRouterPython(normalizedAuth), "utf-8");
|
|
431
|
+
}
|
|
432
|
+
|
|
403
433
|
const blueprintsDir = path.join(process.cwd(), functionsDir, "blueprints");
|
|
404
434
|
const blueprintPath = path.join(blueprintsDir, `${modelKebab.replace(/-/g, "_")}.py`);
|
|
405
435
|
fs.mkdirSync(blueprintsDir, { recursive: true });
|
|
@@ -410,6 +440,20 @@ async function generateFunctionsCode(
|
|
|
410
440
|
console.log(`✅ Created: ${blueprintPath}`);
|
|
411
441
|
}
|
|
412
442
|
|
|
443
|
+
function createUIAuthOptions(policy: ModelAuthPolicy, authConfig: AuthConfig): UIAuthOptions {
|
|
444
|
+
const normalized = normalizeAuthConfig(authConfig);
|
|
445
|
+
const readPolicyName = typeof policy.read === 'string' ? policy.read : policy.policy;
|
|
446
|
+
const writePolicyName = typeof policy.write === 'string' ? policy.write : policy.policy;
|
|
447
|
+
const readNamed = readPolicyName ? normalized?.authorization.policies[readPolicyName] : undefined;
|
|
448
|
+
const named = writePolicyName ? normalized?.authorization.policies[writePolicyName] : undefined;
|
|
449
|
+
const writeRoles = named?.roles ?? (Array.isArray(policy.write) ? policy.write : policy.roles) ?? [];
|
|
450
|
+
const externalScheme = [...(readNamed?.schemes ?? []), ...(named?.schemes ?? [])].find(name => normalized?.schemes[name]?.provider === 'external-token');
|
|
451
|
+
const authScheme = readNamed?.schemes[0] ?? named?.schemes[0];
|
|
452
|
+
const authenticatedFetchImport = externalScheme ? `@/lib/auth/schemes/${toKebabCase(externalScheme)}/authenticated-fetch` : authConfig.provider === 'external-token' ? '@/lib/auth/authenticated-fetch' : undefined;
|
|
453
|
+
const authContextImport = authScheme ? `@/lib/auth/schemes/${toKebabCase(authScheme)}/auth-context` : '@/lib/auth/auth-context';
|
|
454
|
+
return { authPolicy: policy, writeRoles, authenticatedFetchImport, authContextImport };
|
|
455
|
+
}
|
|
456
|
+
|
|
413
457
|
/**
|
|
414
458
|
* コネクタモデル用 Azure Functions コード生成
|
|
415
459
|
*/
|
package/src/cli/index.ts
CHANGED
|
@@ -171,9 +171,11 @@ export function createProgram(devCommandOverride: Command = devCommand): Command
|
|
|
171
171
|
.command("add-auth")
|
|
172
172
|
.description("Add authentication and authorization to the project")
|
|
173
173
|
.option("--provider <provider>", "Auth provider: custom-jwt | swa | external-token | swa-custom | none", "custom-jwt")
|
|
174
|
+
.option("--scheme <name>", "Add a named authentication scheme")
|
|
174
175
|
.action((options) => {
|
|
175
176
|
addAuthCommand({
|
|
176
177
|
provider: options.provider,
|
|
178
|
+
scheme: options.scheme,
|
|
177
179
|
});
|
|
178
180
|
});
|
|
179
181
|
|