@hotfusion/modeller 0.0.13 → 0.0.16

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 (104) hide show
  1. package/README.md +99 -0
  2. package/dist/adapters/cipher.js +51 -0
  3. package/dist/adapters/cipher.js.map +1 -0
  4. package/dist/connector.js +81 -41
  5. package/dist/connector.js.map +1 -1
  6. package/dist/core.js +2 -48
  7. package/dist/core.js.map +1 -1
  8. package/dist/index.js +9 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/model.js +27 -50
  11. package/dist/model.js.map +1 -1
  12. package/dist/oidc/adapter.js +177 -0
  13. package/dist/oidc/adapter.js.map +1 -0
  14. package/dist/oidc/adapters/cipher.js +51 -0
  15. package/dist/oidc/adapters/cipher.js.map +1 -0
  16. package/dist/oidc/client.js +66 -0
  17. package/dist/oidc/client.js.map +1 -0
  18. package/dist/oidc/code.js +37 -0
  19. package/dist/oidc/code.js.map +1 -0
  20. package/dist/oidc/default.config.js +200 -0
  21. package/dist/oidc/default.config.js.map +1 -0
  22. package/dist/oidc/federation.js +51 -0
  23. package/dist/oidc/federation.js.map +1 -0
  24. package/dist/oidc/grant.js +37 -0
  25. package/dist/oidc/grant.js.map +1 -0
  26. package/dist/oidc/interaction.js +36 -0
  27. package/dist/oidc/interaction.js.map +1 -0
  28. package/dist/oidc/oidc.config.js +79 -0
  29. package/dist/oidc/oidc.config.js.map +1 -0
  30. package/dist/oidc/schemas/client.schema.json +62 -0
  31. package/dist/oidc/schemas/code.schema.json +16 -0
  32. package/dist/oidc/schemas/grant.schema.json +13 -0
  33. package/dist/oidc/schemas/interaction.schema.json +26 -0
  34. package/dist/oidc/schemas/session.schema.json +14 -0
  35. package/dist/oidc/schemas/token.schema.json +16 -0
  36. package/dist/oidc/schemas/user.schema.json +44 -0
  37. package/dist/oidc/session.js +36 -0
  38. package/dist/oidc/session.js.map +1 -0
  39. package/dist/oidc/session.token.js +24 -0
  40. package/dist/oidc/session.token.js.map +1 -0
  41. package/dist/oidc/token.js +23 -0
  42. package/dist/oidc/token.js.map +1 -0
  43. package/dist/oidc/user.js +95 -0
  44. package/dist/oidc/user.js.map +1 -0
  45. package/dist/oidc/utils.js +154 -0
  46. package/dist/oidc/utils.js.map +1 -0
  47. package/dist/server.js +722 -113
  48. package/dist/server.js.map +1 -1
  49. package/dist/types/adapters/cipher.d.ts +12 -0
  50. package/dist/types/adapters/cipher.d.ts.map +1 -0
  51. package/dist/types/connector.d.ts +13 -1
  52. package/dist/types/connector.d.ts.map +1 -1
  53. package/dist/types/core.d.ts +2 -2
  54. package/dist/types/core.d.ts.map +1 -1
  55. package/dist/types/index.d.ts +4 -0
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/dist/types/model.d.ts +26 -2
  58. package/dist/types/model.d.ts.map +1 -1
  59. package/dist/types/oidc/adapter.d.ts +16 -0
  60. package/dist/types/oidc/adapter.d.ts.map +1 -0
  61. package/dist/types/oidc/adapters/cipher.d.ts +12 -0
  62. package/dist/types/oidc/adapters/cipher.d.ts.map +1 -0
  63. package/dist/types/oidc/client.d.ts +3 -0
  64. package/dist/types/oidc/client.d.ts.map +1 -0
  65. package/dist/types/oidc/code.d.ts +3 -0
  66. package/dist/types/oidc/code.d.ts.map +1 -0
  67. package/dist/types/oidc/default.config.d.ts +33 -0
  68. package/dist/types/oidc/default.config.d.ts.map +1 -0
  69. package/dist/types/oidc/federation.d.ts +3 -0
  70. package/dist/types/oidc/federation.d.ts.map +1 -0
  71. package/dist/types/oidc/grant.d.ts +3 -0
  72. package/dist/types/oidc/grant.d.ts.map +1 -0
  73. package/dist/types/oidc/interaction.d.ts +3 -0
  74. package/dist/types/oidc/interaction.d.ts.map +1 -0
  75. package/dist/types/oidc/oidc.config.d.ts +7 -0
  76. package/dist/types/oidc/oidc.config.d.ts.map +1 -0
  77. package/dist/types/oidc/session.d.ts +3 -0
  78. package/dist/types/oidc/session.d.ts.map +1 -0
  79. package/dist/types/oidc/session.token.d.ts +3 -0
  80. package/dist/types/oidc/session.token.d.ts.map +1 -0
  81. package/dist/types/oidc/token.d.ts +3 -0
  82. package/dist/types/oidc/token.d.ts.map +1 -0
  83. package/dist/types/oidc/user.d.ts +3 -0
  84. package/dist/types/oidc/user.d.ts.map +1 -0
  85. package/dist/types/oidc/utils.d.ts +56 -0
  86. package/dist/types/oidc/utils.d.ts.map +1 -0
  87. package/dist/types/server.d.ts +8 -3
  88. package/dist/types/server.d.ts.map +1 -1
  89. package/dist/types/types.d.ts +264 -0
  90. package/dist/types/utils/bundler.d.ts.map +1 -1
  91. package/dist/types/utils/display.d.ts +23 -0
  92. package/dist/types/utils/display.d.ts.map +1 -0
  93. package/dist/utils/_secret.key +1 -0
  94. package/dist/utils/bundler.js +48 -8
  95. package/dist/utils/bundler.js.map +1 -1
  96. package/dist/utils/display.js +207 -0
  97. package/dist/utils/display.js.map +1 -0
  98. package/package.json +28 -4
  99. package/docs/CORE.md +0 -191
  100. package/docs/ERRORS.md +0 -90
  101. package/docs/MODEL.md +0 -296
  102. package/docs/PATTERNS.md +0 -182
  103. package/docs/SERVER.md +0 -88
  104. package/docs/UTILITIES.md +0 -111
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CipherAdapter = void 0;
4
+ const core_1 = require("../../core");
5
+ const cipher_1 = require("@hotfusion/cipher");
6
+ class CipherAdapter extends core_1.Adapter {
7
+ cipher;
8
+ ready;
9
+ id;
10
+ constructor(id) {
11
+ super(id);
12
+ this.id = id;
13
+ // Password resolved inside Cipher from:
14
+ // 1. VAULT_PASSWORD env var
15
+ // 2. --password=xxx CLI arg
16
+ this.cipher = new cipher_1.Cipher({
17
+ path: `./vault/${id}`,
18
+ password: process.env.VAULT_PASSWORD || '',
19
+ //@ts-ignore
20
+ locked: false,
21
+ readonly: false,
22
+ }, [{ name: id, schema: {} }, { name: 'trash', schema: {} }]);
23
+ this.ready = this.cipher.ready();
24
+ }
25
+ async sync(id, doc) {
26
+ await this.ready;
27
+ const col = this.cipher.collection(id);
28
+ const key = { id: doc._id.toString() };
29
+ const existing = col.find(key);
30
+ if (existing) {
31
+ await col.update(key, doc);
32
+ }
33
+ else {
34
+ await col.insert(key, doc);
35
+ }
36
+ }
37
+ async pull() {
38
+ await this.ready;
39
+ const col = this.cipher.collection(this.id);
40
+ return col.list()
41
+ .map((entry) => {
42
+ const id = Object.values(entry.key)[0];
43
+ if (!id)
44
+ return null;
45
+ return col.unseal(id);
46
+ })
47
+ .filter(Boolean);
48
+ }
49
+ }
50
+ exports.CipherAdapter = CipherAdapter;
51
+ //# sourceMappingURL=cipher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cipher.js","sourceRoot":"","sources":["../../../src/oidc/adapters/cipher.ts"],"names":[],"mappings":";;;AAAA,qCAAqC;AAGrC,8CAA4C;AAE5C,MAAa,aAAc,SAAQ,cAAO;IAC9B,MAAM,CAAU;IAChB,KAAK,CAAkB;IACvB,EAAE,CAAc;IAExB,YAAY,EAAU;QAClB,KAAK,CAAC,EAAE,CAAC,CAAC;QACV,IAAI,CAAC,EAAE,GAAO,EAAE,CAAC;QACjB,wCAAwC;QACxC,8BAA8B;QAC9B,8BAA8B;QAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,eAAM,CAAC;YACrB,IAAI,EAAO,WAAW,EAAE,EAAE;YAC1B,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;YAC3C,YAAY;YACZ,MAAM,EAAK,KAAK;YAChB,QAAQ,EAAG,KAAK;SACnB,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAU,EAAE,GAA0C;QAC7D,MAAM,IAAI,CAAC,KAAK,CAAC;QACjB,MAAM,GAAG,GAAQ,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE/B,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACN,MAAM,IAAI,CAAC,KAAK,CAAC;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,GAAG,CAAC,IAAI,EAAE;aACZ,GAAG,CAAC,CAAC,KAAS,EAAE,EAAE;YACf,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YACrB,OAAO,GAAG,CAAC,MAAM,CAAC,EAAS,CAAC,CAAC;QACjC,CAAC,CAAC;aACD,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;CACJ;AA7CD,sCA6CC"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ClientModel = void 0;
7
+ const model_1 = require("../model");
8
+ const client_schema_json_1 = __importDefault(require("./schemas/client.schema.json"));
9
+ const cipher_1 = require("./adapters/cipher");
10
+ const utils_1 = require("./utils");
11
+ exports.ClientModel = new model_1.Model('client', client_schema_json_1.default, {
12
+ adapter: cipher_1.CipherAdapter,
13
+ trash: false
14
+ })
15
+ .hook('client-before-insert', {
16
+ on: 'before:insert',
17
+ callback: async (payload) => {
18
+ if (payload.data._sync)
19
+ return;
20
+ try {
21
+ const { client_id, client_secret, redirect_uris } = payload.data;
22
+ if (!client_id || !client_secret || !redirect_uris?.length) {
23
+ throw { code: 'MISSING_REQUIRED_FIELDS' };
24
+ }
25
+ if (!payload.data.grant_types)
26
+ payload.data.grant_types = ['authorization_code', 'refresh_token'];
27
+ if (!payload.data.response_types)
28
+ payload.data.response_types = ['code'];
29
+ if (!payload.data.token_endpoint_auth_method)
30
+ payload.data.token_endpoint_auth_method = 'client_secret_basic';
31
+ if (!payload.data.scopes)
32
+ payload.data.scopes = ['openid', 'email', 'profile'];
33
+ if (!payload.data.providers)
34
+ payload.data.providers = [];
35
+ if (!payload.data.provider_configs)
36
+ payload.data.provider_configs = [];
37
+ if (payload.data.isActive === undefined)
38
+ payload.data.isActive = true;
39
+ }
40
+ catch (err) {
41
+ throw {
42
+ code: 'CLIENT_INSERT_FAILED',
43
+ message: (0, utils_1.extractError)(err),
44
+ details: err
45
+ };
46
+ }
47
+ }
48
+ })
49
+ .hook('client-before-delete', {
50
+ on: 'before:delete',
51
+ callback: async (payload) => {
52
+ if (payload.key?._sync)
53
+ return;
54
+ try {
55
+ const client = await exports.ClientModel.get({ _id: payload.key._id });
56
+ console.log(`[Client] Deleting client: ${client.client_id}`);
57
+ }
58
+ catch (err) {
59
+ throw {
60
+ code: 'CLIENT_DELETE_FAILED',
61
+ message: (0, utils_1.extractError)(err)
62
+ };
63
+ }
64
+ }
65
+ });
66
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/oidc/client.ts"],"names":[],"mappings":";;;;;;AAAA,oCAAiC;AACjC,sFAAkD;AAClD,8CAAkD;AAClD,mCAAuC;AAE1B,QAAA,WAAW,GAAG,IAAI,aAAK,CAAC,QAAQ,EAAE,4BAAM,EAAE;IACnD,OAAO,EAAE,sBAAa;IACtB,KAAK,EAAE,KAAK;CACf,CAAC;KACG,IAAI,CAAC,sBAAsB,EAAE;IAC1B,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAC/B,IAAI,CAAC;YACD,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YACjE,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;gBACzD,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;YAC9C,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW;gBAAQ,OAAO,CAAC,IAAI,CAAC,WAAW,GAAS,CAAC,oBAAoB,EAAE,eAAe,CAAC,CAAC;YAC9G,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc;gBAAK,OAAO,CAAC,IAAI,CAAC,cAAc,GAAM,CAAC,MAAM,CAAC,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,0BAA0B;gBAAE,OAAO,CAAC,IAAI,CAAC,0BAA0B,GAAG,qBAAqB,CAAC;YAC9G,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM;gBAAa,OAAO,CAAC,IAAI,CAAC,MAAM,GAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YACrG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS;gBAAU,OAAO,CAAC,IAAI,CAAC,SAAS,GAAW,EAAE,CAAC;YACzE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB;gBAAG,OAAO,CAAC,IAAI,CAAC,gBAAgB,GAAI,EAAE,CAAC;YACzE,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAQ,IAAI,CAAC;QAC/E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM;gBACF,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,IAAA,oBAAY,EAAC,GAAG,CAAC;gBAC1B,OAAO,EAAE,GAAG;aACf,CAAC;QACN,CAAC;IACL,CAAC;CACJ,CAAC;KAED,IAAI,CAAC,sBAAsB,EAAE;IAC1B,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK;YAAE,OAAO;QAC/B,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,mBAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,6BAA6B,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM;gBACF,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,IAAA,oBAAY,EAAC,GAAG,CAAC;aAC7B,CAAC;QACN,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CodeModel = void 0;
7
+ const model_1 = require("../model");
8
+ const code_schema_json_1 = __importDefault(require("./schemas/code.schema.json"));
9
+ const cipher_1 = require("./adapters/cipher");
10
+ const utils_1 = require("./utils");
11
+ exports.CodeModel = new model_1.Model('code', code_schema_json_1.default, {
12
+ adapter: cipher_1.CipherAdapter,
13
+ trash: false
14
+ })
15
+ .hook('code-before-insert', {
16
+ on: 'before:insert',
17
+ callback: async (payload) => {
18
+ if (payload.data._sync)
19
+ return;
20
+ try {
21
+ const { jti, clientId, accountId } = payload.data;
22
+ if (!jti || !clientId || !accountId) {
23
+ throw { code: 'MISSING_REQUIRED_FIELDS' };
24
+ }
25
+ if (payload.data.consumed === undefined)
26
+ payload.data.consumed = false;
27
+ }
28
+ catch (err) {
29
+ throw {
30
+ code: 'CODE_INSERT_FAILED',
31
+ message: (0, utils_1.extractError)(err),
32
+ details: err
33
+ };
34
+ }
35
+ }
36
+ });
37
+ //# sourceMappingURL=code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/oidc/code.ts"],"names":[],"mappings":";;;;;;AAAA,oCAAiC;AACjC,kFAAgD;AAChD,8CAAkD;AAClD,mCAAuC;AAE1B,QAAA,SAAS,GAAG,IAAI,aAAK,CAAC,MAAM,EAAE,0BAAM,EAAE;IAC/C,OAAO,EAAE,sBAAa;IACtB,KAAK,EAAE,KAAK;CACf,CAAC;KACG,IAAI,CAAC,oBAAoB,EAAE;IACxB,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAC/B,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAClD,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;gBAClC,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;YAC9C,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC3E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM;gBACF,IAAI,EAAE,oBAAoB;gBAC1B,OAAO,EAAE,IAAA,oBAAY,EAAC,GAAG,CAAC;gBAC1B,OAAO,EAAE,GAAG;aACf,CAAC;QACN,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OIDCConfig = void 0;
7
+ exports.resolveJWKS = resolveJWKS;
8
+ const jose_1 = require("jose");
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const JWKS_PATH = node_path_1.default.resolve(process.cwd(), './data/oidc.jwks.json');
12
+ // ==============================================================================
13
+ // JWKS — env → disk → generate
14
+ // ==============================================================================
15
+ async function resolveJWKS() {
16
+ if (process.env.OIDC_JWKS) {
17
+ try {
18
+ return JSON.parse(process.env.OIDC_JWKS);
19
+ }
20
+ catch {
21
+ throw new Error('[OIDC] Failed to parse OIDC_JWKS env variable');
22
+ }
23
+ }
24
+ if (node_fs_1.default.existsSync(JWKS_PATH)) {
25
+ try {
26
+ return JSON.parse(node_fs_1.default.readFileSync(JWKS_PATH, 'utf-8'));
27
+ }
28
+ catch {
29
+ throw new Error('[OIDC] Failed to read JWKS from disk');
30
+ }
31
+ }
32
+ const { privateKey } = await (0, jose_1.generateKeyPair)('RS256', { extractable: true });
33
+ const jwk = await (0, jose_1.exportJWK)(privateKey);
34
+ jwk.use = 'sig';
35
+ jwk.alg = 'RS256';
36
+ jwk.kid = `key-${Date.now()}`;
37
+ const jwks = { keys: [jwk] };
38
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(JWKS_PATH), { recursive: true });
39
+ node_fs_1.default.writeFileSync(JWKS_PATH, JSON.stringify(jwks, null, 2), 'utf-8');
40
+ return jwks;
41
+ }
42
+ // ==============================================================================
43
+ // Base OIDCConfig
44
+ // Abstract — no imports from modeller model stack.
45
+ // Everything is resolved dynamically via the model instance at runtime.
46
+ // Extend this class in your model; override only what you need.
47
+ // ==============================================================================
48
+ class OIDCConfig {
49
+ // ?? Developer overrides (optional) ????????????????????????????????????????
50
+ // OIDC issuer URL
51
+ static issuer;
52
+ // Additional registered clients beyond the default one
53
+ static clients;
54
+ // Federation providers — empty by default (username/password only)
55
+ static federation;
56
+ // Override the adapter — must be a class compatible with node-oidc-provider adapter spec
57
+ // Defaults to the modeller OIDCAdapter resolved from model at runtime
58
+ static adapter;
59
+ // Override account resolution
60
+ static findAccount;
61
+ // Override user verification
62
+ static verifyUser;
63
+ // Override federated user resolution
64
+ static findOrCreateFederatedUser;
65
+ // Override TTLs (merged with defaults)
66
+ static ttl;
67
+ // Override scopes
68
+ static scopes;
69
+ // Override claims
70
+ static claims;
71
+ // ?? Internal methods — called by server, not meant to be overridden ????????
72
+ static _getIssuer(port) {
73
+ return this.issuer
74
+ ?? process.env.ISSUER_URL
75
+ ?? `http://localhost:${port}`;
76
+ }
77
+ static _getAdapter(defaultAdapter) {
78
+ // Use static override if provided, otherwise use the default passed by server
79
+ return this.adapter ?? defaultAdapter;
80
+ }
81
+ static _getScopes() {
82
+ return this.scopes ?? ['openid', 'email', 'profile'];
83
+ }
84
+ static _getClaims() {
85
+ return this.claims ?? {
86
+ openid: ['sub'],
87
+ email: ['email'],
88
+ profile: ['username', 'name'],
89
+ };
90
+ }
91
+ static _getTTL() {
92
+ return {
93
+ AccessToken: 60 * 60,
94
+ AuthorizationCode: 10 * 60,
95
+ IdToken: 60 * 60,
96
+ RefreshToken: 14 * 24 * 60 * 60,
97
+ Session: 14 * 24 * 60 * 60,
98
+ Interaction: 60 * 60,
99
+ Grant: 14 * 24 * 60 * 60,
100
+ ...((this.ttl) ?? {}),
101
+ };
102
+ }
103
+ static _buildDefaultClient(issuer) {
104
+ return {
105
+ client_id: 'default',
106
+ client_secret: 'default-secret',
107
+ redirect_uris: [`${issuer}/auth/callback`],
108
+ grant_types: ['authorization_code'],
109
+ response_types: ['code'],
110
+ token_endpoint_auth_method: 'client_secret_basic',
111
+ scopes: ['openid', 'email', 'profile'],
112
+ isActive: true,
113
+ };
114
+ }
115
+ static async _seedClients(issuer, adapter) {
116
+ console.log('[OIDC] _seedClients start, adapter:', adapter?.name);
117
+ const clientAdapter = new adapter('Client');
118
+ console.log('[OIDC] clientAdapter created');
119
+ const allClients = [
120
+ this._buildDefaultClient(issuer),
121
+ ...(this.clients ?? []),
122
+ ];
123
+ for (const client of allClients) {
124
+ try {
125
+ const existing = await clientAdapter.find(client.client_id);
126
+ if (!existing) {
127
+ await clientAdapter.upsert(client.client_id, client, 0);
128
+ }
129
+ }
130
+ catch (err) {
131
+ throw { ...err, model: 'ClientModel', client_id: client.client_id };
132
+ }
133
+ }
134
+ }
135
+ static async _findAccount(ctx, id, model) {
136
+ const fn = this.findAccount;
137
+ if (fn)
138
+ return fn(ctx, id, model);
139
+ const user = await model.user?.get({ _id: id }, { private: false });
140
+ if (!user)
141
+ return undefined;
142
+ return {
143
+ accountId: user._id,
144
+ claims: async () => ({
145
+ sub: user._id,
146
+ email: user.email,
147
+ username: user.username,
148
+ }),
149
+ };
150
+ }
151
+ static async _verifyUser(username, password, model) {
152
+ const fn = this.verifyUser;
153
+ if (fn)
154
+ return fn(username, password, model);
155
+ return model.user?.call('verify', { username, password });
156
+ }
157
+ static async _findOrCreateFederatedUser(email, model) {
158
+ const fn = this.findOrCreateFederatedUser;
159
+ if (fn)
160
+ return fn(email, model);
161
+ let user = await model.user?.get({ email }).catch(() => null);
162
+ if (!user) {
163
+ user = await model.user?.insert({
164
+ username: email,
165
+ email: email,
166
+ password: Math.random().toString(36),
167
+ isActive: true,
168
+ roles: 'user',
169
+ _sync: true,
170
+ });
171
+ }
172
+ return user;
173
+ }
174
+ static async _buildProviderConfig(issuer, secret) {
175
+ const jwks = await resolveJWKS();
176
+ return {
177
+ jwks,
178
+ features: {
179
+ devInteractions: { enabled: false },
180
+ clientCredentials: { enabled: true },
181
+ introspection: { enabled: true },
182
+ revocation: { enabled: true },
183
+ rpInitiatedLogout: { enabled: true },
184
+ },
185
+ scopes: this._getScopes(),
186
+ claims: this._getClaims(),
187
+ ttl: this._getTTL(),
188
+ pkce: {
189
+ required: () => false,
190
+ },
191
+ cookies: {
192
+ keys: [process.env.OIDC_COOKIE_SECRET ?? secret],
193
+ short: { secure: false, sameSite: 'lax' },
194
+ long: { secure: false, sameSite: 'lax' },
195
+ },
196
+ };
197
+ }
198
+ }
199
+ exports.OIDCConfig = OIDCConfig;
200
+ //# sourceMappingURL=default.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default.config.js","sourceRoot":"","sources":["../../src/oidc/default.config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FederationModel = void 0;
4
+ const model_1 = require("../model");
5
+ const cipher_1 = require("./adapters/cipher");
6
+ const utils_1 = require("./utils");
7
+ const schema = {
8
+ "$schema": "http://json-schema.org/draft-07/schema#",
9
+ "type": "object",
10
+ "properties": {
11
+ "name": { "type": "string", "label": "Provider Name", "description": "e.g. google, github" },
12
+ "client_id": { "type": "string", "label": "Client ID" },
13
+ "client_secret": { "type": "string", "label": "Client Secret", "private": true },
14
+ "issuer": { "type": "string", "label": "Issuer URL", "description": "e.g. https://accounts.google.com" },
15
+ "scopes": { "type": "string", "label": "Scopes", "description": "e.g. openid email profile" },
16
+ "isActive": { "type": "boolean", "label": "Active" }
17
+ },
18
+ "required": ["name", "client_id", "client_secret", "issuer"]
19
+ };
20
+ exports.FederationModel = new model_1.Model('federation', schema, {
21
+ adapter: cipher_1.CipherAdapter,
22
+ trash: false,
23
+ })
24
+ .hook('federation-before-insert', {
25
+ on: 'before:insert',
26
+ callback: async (payload) => {
27
+ if (payload.data._sync)
28
+ return;
29
+ try {
30
+ const { name, client_id, client_secret, issuer } = payload.data;
31
+ if (!name || !client_id || !client_secret || !issuer) {
32
+ throw { code: 'MISSING_REQUIRED_FIELDS' };
33
+ }
34
+ if (!payload.data.scopes)
35
+ payload.data.scopes = 'openid email profile';
36
+ if (payload.data.isActive === undefined)
37
+ payload.data.isActive = true;
38
+ }
39
+ catch (err) {
40
+ throw { code: 'FEDERATION_INSERT_FAILED', message: (0, utils_1.extractError)(err), details: err };
41
+ }
42
+ }
43
+ })
44
+ .hook('federation-before-delete', {
45
+ on: 'before:delete',
46
+ callback: async (payload) => {
47
+ if (payload.key?._sync)
48
+ return;
49
+ }
50
+ });
51
+ //# sourceMappingURL=federation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation.js","sourceRoot":"","sources":["../../src/oidc/federation.ts"],"names":[],"mappings":";;;AAAA,oCAAyC;AACzC,8CAAkD;AAClD,mCAAwC;AAExC,MAAM,MAAM,GAAG;IACX,SAAS,EAAM,yCAAyC;IACxD,MAAM,EAAS,QAAQ;IACvB,YAAY,EAAG;QACX,MAAM,EAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAI,aAAa,EAAE,qBAAqB,EAAE;QACxG,WAAW,EAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAA8C;QACxG,eAAe,EAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAG,SAAS,EAAE,IAAI,EAAuB;QACvG,QAAQ,EAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAO,aAAa,EAAE,kCAAkC,EAAE;QACrH,QAAQ,EAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAW,aAAa,EAAE,2BAA2B,EAAS;QACrH,UAAU,EAAQ,EAAE,MAAM,EAAE,SAAS,EAAC,OAAO,EAAE,QAAQ,EAAkD;KAC5G;IACD,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,CAAC;CAC/D,CAAC;AAEW,QAAA,eAAe,GAAG,IAAI,aAAK,CAAC,YAAY,EAAE,MAAM,EAAE;IAC3D,OAAO,EAAG,sBAAa;IACvB,KAAK,EAAK,KAAK;CAClB,CAAC;KACG,IAAI,CAAC,0BAA0B,EAAE;IAC9B,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAC/B,IAAI,CAAC;YACD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAChE,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM,EAAE,CAAC;gBACnD,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;YAC9C,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM;gBAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAK,sBAAsB,CAAC;YAC3E,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,IAAA,oBAAY,EAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QACzF,CAAC;IACL,CAAC;CACJ,CAAC;KACD,IAAI,CAAC,0BAA0B,EAAE;IAC9B,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK;YAAE,OAAO;IACnC,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GrantModel = void 0;
7
+ const model_1 = require("../model");
8
+ const grant_schema_json_1 = __importDefault(require("./schemas/grant.schema.json"));
9
+ const cipher_1 = require("./adapters/cipher");
10
+ const utils_1 = require("./utils");
11
+ exports.GrantModel = new model_1.Model('grant', grant_schema_json_1.default, {
12
+ adapter: cipher_1.CipherAdapter,
13
+ trash: false
14
+ })
15
+ .hook('grant-before-insert', {
16
+ on: 'before:insert',
17
+ callback: async (payload) => {
18
+ if (payload.data._sync)
19
+ return;
20
+ try {
21
+ const { jti, clientId, accountId } = payload.data;
22
+ if (!jti || !clientId || !accountId) {
23
+ throw { code: 'MISSING_REQUIRED_FIELDS' };
24
+ }
25
+ if (payload.data.consumed === undefined)
26
+ payload.data.consumed = false;
27
+ }
28
+ catch (err) {
29
+ throw {
30
+ code: 'GRANT_INSERT_FAILED',
31
+ message: (0, utils_1.extractError)(err),
32
+ details: err
33
+ };
34
+ }
35
+ }
36
+ });
37
+ //# sourceMappingURL=grant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grant.js","sourceRoot":"","sources":["../../src/oidc/grant.ts"],"names":[],"mappings":";;;;;;AAAA,oCAAiC;AACjC,oFAAiD;AACjD,8CAAkD;AAClD,mCAAuC;AAE1B,QAAA,UAAU,GAAG,IAAI,aAAK,CAAC,OAAO,EAAE,2BAAM,EAAE;IACjD,OAAO,EAAE,sBAAa;IACtB,KAAK,EAAE,KAAK;CACf,CAAC;KACG,IAAI,CAAC,qBAAqB,EAAE;IACzB,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAC/B,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAClD,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;gBAClC,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;YAC9C,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC3E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM;gBACF,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,IAAA,oBAAY,EAAC,GAAG,CAAC;gBAC1B,OAAO,EAAE,GAAG;aACf,CAAC;QACN,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InteractionModel = void 0;
7
+ const model_1 = require("../model");
8
+ const interaction_schema_json_1 = __importDefault(require("./schemas/interaction.schema.json"));
9
+ const cipher_1 = require("./adapters/cipher");
10
+ const utils_1 = require("./utils");
11
+ exports.InteractionModel = new model_1.Model('interaction', interaction_schema_json_1.default, {
12
+ adapter: cipher_1.CipherAdapter,
13
+ trash: false
14
+ })
15
+ .hook('interaction-before-insert', {
16
+ on: 'before:insert',
17
+ callback: async (payload) => {
18
+ if (payload.data._sync)
19
+ return;
20
+ try {
21
+ const { jti } = payload.data;
22
+ if (!jti)
23
+ throw { code: 'MISSING_REQUIRED_FIELDS' };
24
+ if (payload.data.consumed === undefined)
25
+ payload.data.consumed = false;
26
+ }
27
+ catch (err) {
28
+ throw {
29
+ code: 'INTERACTION_INSERT_FAILED',
30
+ message: (0, utils_1.extractError)(err),
31
+ details: err
32
+ };
33
+ }
34
+ }
35
+ });
36
+ //# sourceMappingURL=interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction.js","sourceRoot":"","sources":["../../src/oidc/interaction.ts"],"names":[],"mappings":";;;;;;AAAA,oCAAiC;AACjC,gGAAuD;AACvD,8CAAkD;AAClD,mCAAuC;AAE1B,QAAA,gBAAgB,GAAG,IAAI,aAAK,CAAC,aAAa,EAAE,iCAAM,EAAE;IAC7D,OAAO,EAAE,sBAAa;IACtB,KAAK,EAAE,KAAK;CACf,CAAC;KACG,IAAI,CAAC,2BAA2B,EAAE;IAC/B,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,KAAK,EAAE,OAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAC/B,IAAI,CAAC;YACD,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAC7B,IAAI,CAAC,GAAG;gBAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;YACpD,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC3E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM;gBACF,IAAI,EAAE,2BAA2B;gBACjC,OAAO,EAAE,IAAA,oBAAY,EAAC,GAAG,CAAC;gBAC1B,OAAO,EAAE,GAAG;aACf,CAAC;QACN,CAAC;IACL,CAAC;CACJ,CAAC,CAAC"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createOIDCConfig = createOIDCConfig;
7
+ const jose_1 = require("jose");
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const JWKS_PATH = node_path_1.default.resolve(process.cwd(), './data/oidc.jwks.json');
11
+ async function resolveJWKS() {
12
+ if (process.env.OIDC_JWKS) {
13
+ try {
14
+ return JSON.parse(process.env.OIDC_JWKS);
15
+ }
16
+ catch {
17
+ throw new Error('[OIDC] Failed to parse OIDC_JWKS env variable');
18
+ }
19
+ }
20
+ if (node_fs_1.default.existsSync(JWKS_PATH)) {
21
+ try {
22
+ return JSON.parse(node_fs_1.default.readFileSync(JWKS_PATH, 'utf-8'));
23
+ }
24
+ catch {
25
+ throw new Error('[OIDC] Failed to read JWKS from disk');
26
+ }
27
+ }
28
+ const { privateKey } = await (0, jose_1.generateKeyPair)('RS256', { extractable: true });
29
+ const jwk = await (0, jose_1.exportJWK)(privateKey);
30
+ jwk.use = 'sig';
31
+ jwk.alg = 'RS256';
32
+ jwk.kid = `key-${Date.now()}`;
33
+ const jwks = { keys: [jwk] };
34
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(JWKS_PATH), { recursive: true });
35
+ node_fs_1.default.writeFileSync(JWKS_PATH, JSON.stringify(jwks, null, 2), 'utf-8');
36
+ return jwks;
37
+ }
38
+ async function createOIDCConfig(opts) {
39
+ const { issuer, secret, findAccount } = opts;
40
+ const jwks = await resolveJWKS();
41
+ return {
42
+ jwks,
43
+ findAccount,
44
+ interactions: {
45
+ url: (ctx, interaction) => `/interaction/${interaction.uid}`,
46
+ },
47
+ features: {
48
+ devInteractions: { enabled: false },
49
+ clientCredentials: { enabled: true },
50
+ introspection: { enabled: true },
51
+ revocation: { enabled: true },
52
+ rpInitiatedLogout: { enabled: true },
53
+ },
54
+ claims: {
55
+ openid: ['sub'],
56
+ email: ['email'],
57
+ profile: ['username', 'name'],
58
+ },
59
+ scopes: ['openid', 'email', 'profile'],
60
+ pkce: {
61
+ required: () => false,
62
+ },
63
+ ttl: {
64
+ AccessToken: 60 * 60,
65
+ AuthorizationCode: 10 * 60,
66
+ IdToken: 60 * 60,
67
+ RefreshToken: 14 * 24 * 60 * 60,
68
+ Session: 14 * 24 * 60 * 60,
69
+ Interaction: 60 * 60,
70
+ Grant: 14 * 24 * 60 * 60,
71
+ },
72
+ cookies: {
73
+ keys: [process.env.OIDC_COOKIE_SECRET ?? secret],
74
+ short: { secure: false, sameSite: 'lax' },
75
+ long: { secure: false, sameSite: 'lax' },
76
+ },
77
+ };
78
+ }
79
+ //# sourceMappingURL=oidc.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc.config.js","sourceRoot":"","sources":["../../src/oidc/oidc.config.ts"],"names":[],"mappings":"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"}