@maka/maka-cli 5.123.1 → 5.125.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/README.md +64 -64
- package/bundle/typescript/package.json +120 -120
- package/bundle/typescript/src/README.md +64 -64
- package/bundle/typescript/src/commands/aws/aws.command.js +2 -2
- package/bundle/typescript/src/commands/aws/ci.sub.cmd.js +5 -5
- package/bundle/typescript/src/commands/aws/ckp.sub.cmd.js +12 -12
- package/bundle/typescript/src/commands/aws/csg.sub.cmd.js +3 -3
- package/bundle/typescript/src/commands/aws/di.sub.cmd.js +8 -8
- package/bundle/typescript/src/commands/aws/rkp.sub.cmd.js +5 -5
- package/bundle/typescript/src/commands/aws/sth.sub.cmd.js +3 -3
- package/bundle/typescript/src/commands/aws/ti.sub.cmd.js +5 -5
- package/bundle/typescript/src/commands/build/build.js +16 -16
- package/bundle/typescript/src/commands/build/docker.sub.cmd.js +9 -9
- package/bundle/typescript/src/commands/create.js +36 -36
- package/bundle/typescript/src/commands/debug.js +4 -4
- package/bundle/typescript/src/commands/deploy/deploy.command.js +2 -2
- package/bundle/typescript/src/commands/deploy/galaxy.sub.cmd.js +2 -2
- package/bundle/typescript/src/commands/deploy/github.sub.cmd.js +8 -8
- package/bundle/typescript/src/commands/deploy/ubuntu.sub.cmd.js +2 -2
- package/bundle/typescript/src/commands/env/env.command.js +8 -8
- package/bundle/typescript/src/commands/env/set.sub.cmd.js +11 -11
- package/bundle/typescript/src/commands/game/sideQuest/adept-powers.d.ts +0 -8
- package/bundle/typescript/src/commands/game/sideQuest/adept-powers.js +6 -50
- package/bundle/typescript/src/commands/game/sideQuest/adept-powers.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +3 -3
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/augmentations.d.ts +0 -4
- package/bundle/typescript/src/commands/game/sideQuest/augmentations.js +0 -1342
- package/bundle/typescript/src/commands/game/sideQuest/augmentations.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/catalog.js +5 -6
- package/bundle/typescript/src/commands/game/sideQuest/commands/catalog.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js +13 -5
- package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js +5 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.d.ts +0 -38
- package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js +11 -45
- package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/install.js +5 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/install.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/jump.js +10 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/jump.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/lifestyle.d.ts +7 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/lifestyle.js +58 -9
- package/bundle/typescript/src/commands/game/sideQuest/commands/lifestyle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/quality-trade.js +10 -7
- package/bundle/typescript/src/commands/game/sideQuest/commands/quality-trade.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js +7 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +9 -9
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +12 -8
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sin.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/sin.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/source.js +8 -8
- package/bundle/typescript/src/commands/game/sideQuest/commands/source.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +22 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +24 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.d.ts +39 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js +110 -35
- package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +445 -445
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +6 -6
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +42 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.js +118 -43
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/metamagics.d.ts +32 -0
- package/bundle/typescript/src/commands/game/sideQuest/metamagics.js +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/metamagics.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/metatypes.d.ts +6 -4
- package/bundle/typescript/src/commands/game/sideQuest/metatypes.js +3 -83
- package/bundle/typescript/src/commands/game/sideQuest/metatypes.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/home-containers.d.ts +36 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/home-containers.js +62 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/home-containers.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +206 -206
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +5 -5
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +10 -14
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +24 -10
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/qualities.d.ts +3 -7
- package/bundle/typescript/src/commands/game/sideQuest/qualities.js +15 -715
- package/bundle/typescript/src/commands/game/sideQuest/qualities.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +556 -556
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +1447 -1447
- package/bundle/typescript/src/commands/game/sideQuest/spells.d.ts +5 -7
- package/bundle/typescript/src/commands/game/sideQuest/spells.js +5 -63
- package/bundle/typescript/src/commands/game/sideQuest/spells.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +8 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +22 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.d.ts +36 -20
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js +24 -658
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.d.ts +100 -20
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.js +314 -57
- package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commerce.d.ts +32 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commerce.js +45 -5
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commerce.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/ephemeral.js +14 -14
- package/bundle/typescript/src/commands/game/sideQuest/utilities/owned-drones.d.ts +32 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/owned-drones.js +24 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/owned-drones.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.d.ts +34 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +66 -29
- package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js +2 -2
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +28 -2
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/commands/generate.js +2 -2
- package/bundle/typescript/src/commands/lint.js +10 -10
- package/bundle/typescript/src/commands/maka.cmd.js +26 -26
- package/bundle/typescript/src/commands/murder.js +14 -14
- package/bundle/typescript/src/commands/proxy.js +13 -13
- package/bundle/typescript/src/commands/remote/reconfig.sub.cmd.js +6 -6
- package/bundle/typescript/src/commands/run/docker.sub.cmd.js +11 -11
- package/bundle/typescript/src/commands/run/run.command.js +24 -24
- package/bundle/typescript/src/commands/set/global.sub.cmd.js +8 -8
- package/bundle/typescript/src/commands/set/local.sub.cmd.js +2 -2
- package/bundle/typescript/src/commands/set/set.command.js +3 -3
- package/bundle/typescript/src/commands/testCmd/test.command.js +2 -2
- package/bundle/typescript/src/error.js +1 -1
- package/bundle/typescript/src/error.js.map +1 -1
- package/bundle/typescript/src/exec.js +0 -0
- package/bundle/typescript/src/generators/api.js +11 -11
- package/bundle/typescript/src/generators/collection.js +6 -6
- package/bundle/typescript/src/generators/hook.js +10 -10
- package/bundle/typescript/src/generators/kits/auth/auth.generator.js +2 -2
- package/bundle/typescript/src/generators/kits/auth/auth0-meteor.auth.gen.js +612 -612
- package/bundle/typescript/src/generators/kits/auth/basic-meteor.auth.gen.js +48 -48
- package/bundle/typescript/src/generators/kits/auth/provider.auth.gen.js +12 -12
- package/bundle/typescript/src/generators/kits/esri/esri.generator.js +3 -3
- package/bundle/typescript/src/generators/kits/esri/map.esri.gen.js +7 -7
- package/bundle/typescript/src/generators/kits/frames/frames.generator.js +16 -16
- package/bundle/typescript/src/generators/kits/mui/auth.mui.gen.js +2 -2
- package/bundle/typescript/src/generators/kits/mui/auth0.mui.gen.js +5 -5
- package/bundle/typescript/src/generators/kits/mui/frame.mui.gen.js +4 -4
- package/bundle/typescript/src/generators/kits/mui/mui.generator.js +22 -22
- package/bundle/typescript/src/generators/services/translation.js +5 -5
- package/bundle/typescript/src/templates/aws/cloudformation/create-ec2-instance.template +14 -14
- package/bundle/typescript/src/templates/meteor/api/api.js +20 -20
- package/bundle/typescript/src/templates/meteor/api/api.js.ts +20 -20
- package/bundle/typescript/src/templates/meteor/api/apollo-gateway.js +50 -50
- package/bundle/typescript/src/templates/meteor/api/apollo-gateway.js.ts +55 -55
- package/bundle/typescript/src/templates/meteor/api/graphql-api.js +63 -63
- package/bundle/typescript/src/templates/meteor/api/graphql-api.js.ts +69 -69
- package/bundle/typescript/src/templates/meteor/api/methods.js +39 -39
- package/bundle/typescript/src/templates/meteor/api/methods.js.ts +40 -40
- package/bundle/typescript/src/templates/meteor/api/register-api.js +3 -3
- package/bundle/typescript/src/templates/meteor/api/register-api.js.ts +3 -3
- package/bundle/typescript/src/templates/meteor/api/resolvers.js +9 -9
- package/bundle/typescript/src/templates/meteor/api/resolvers.js.ts +9 -9
- package/bundle/typescript/src/templates/meteor/api/typeDefs.js +6 -6
- package/bundle/typescript/src/templates/meteor/api/typeDefs.js.ts +6 -6
- package/bundle/typescript/src/templates/meteor/app/client/body.html +3 -3
- package/bundle/typescript/src/templates/meteor/app/client/head.html +12 -12
- package/bundle/typescript/src/templates/meteor/app/client/main.js +15 -15
- package/bundle/typescript/src/templates/meteor/app/client/main.js.jsx +15 -15
- package/bundle/typescript/src/templates/meteor/app/client/main.js.ts +17 -17
- package/bundle/typescript/src/templates/meteor/app/client/main.js.tsx +17 -17
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/index.js +20 -20
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/index.js.jsx +107 -107
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/index.js.ts +20 -20
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/index.js.tsx +108 -108
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/routes.js +39 -39
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/routes.js.jsx +33 -33
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/routes.js.ts +24 -24
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/routes.js.tsx +33 -33
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/templates.js +9 -9
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/templates.js.jsx +9 -9
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/templates.js.ts +9 -9
- package/bundle/typescript/src/templates/meteor/app/imports/startup/client/templates.js.tsx +9 -9
- package/bundle/typescript/src/templates/meteor/app/imports/startup/lib/index.js +1 -1
- package/bundle/typescript/src/templates/meteor/app/imports/startup/lib/index.js.jsx +20 -20
- package/bundle/typescript/src/templates/meteor/app/imports/startup/lib/index.js.ts +1 -1
- package/bundle/typescript/src/templates/meteor/app/imports/startup/lib/index.js.tsx +20 -20
- package/bundle/typescript/src/templates/meteor/app/imports/startup/lib/routes.js.jsx +28 -28
- package/bundle/typescript/src/templates/meteor/app/imports/startup/lib/routes.js.tsx +28 -28
- package/bundle/typescript/src/templates/meteor/app/imports/startup/server/index.js +1 -1
- package/bundle/typescript/src/templates/meteor/app/imports/startup/server/index.js.jsx +95 -95
- package/bundle/typescript/src/templates/meteor/app/imports/startup/server/index.js.tsx +98 -98
- package/bundle/typescript/src/templates/meteor/app/imports/ui/test-helpers.js +24 -24
- package/bundle/typescript/src/templates/meteor/app/imports/ui/test-helpers.js.ts +24 -24
- package/bundle/typescript/src/templates/meteor/app/lib/main.js +3 -3
- package/bundle/typescript/src/templates/meteor/app/lib/main.js.jsx +3 -3
- package/bundle/typescript/src/templates/meteor/app/lib/main.js.ts +3 -3
- package/bundle/typescript/src/templates/meteor/app/lib/main.js.tsx +3 -3
- package/bundle/typescript/src/templates/meteor/app/maka.d.ts +533 -533
- package/bundle/typescript/src/templates/meteor/app/meteor.d.ts +181 -181
- package/bundle/typescript/src/templates/meteor/app/public/manifest.json +27 -27
- package/bundle/typescript/src/templates/meteor/app/public/sw.js +30 -30
- package/bundle/typescript/src/templates/meteor/app/public/sw.js.jsx +30 -30
- package/bundle/typescript/src/templates/meteor/app/public/sw.js.ts +30 -30
- package/bundle/typescript/src/templates/meteor/app/public/sw.js.tsx +30 -30
- package/bundle/typescript/src/templates/meteor/app/server/helmet-csp.js +179 -179
- package/bundle/typescript/src/templates/meteor/app/server/helmet-csp.js.jsx +179 -179
- package/bundle/typescript/src/templates/meteor/app/server/helmet-csp.js.ts +179 -179
- package/bundle/typescript/src/templates/meteor/app/server/helmet-csp.js.tsx +179 -179
- package/bundle/typescript/src/templates/meteor/app/server/main.js +13 -13
- package/bundle/typescript/src/templates/meteor/app/server/main.js.jsx +13 -13
- package/bundle/typescript/src/templates/meteor/app/server/main.js.ts +14 -14
- package/bundle/typescript/src/templates/meteor/app/server/main.js.tsx +14 -14
- package/bundle/typescript/src/templates/meteor/app/tsconfig.json +42 -42
- package/bundle/typescript/src/templates/meteor/collection/collection.js +51 -51
- package/bundle/typescript/src/templates/meteor/collection/collection.js.ts +55 -55
- package/bundle/typescript/src/templates/meteor/collection/tests.js +27 -27
- package/bundle/typescript/src/templates/meteor/collection/tests.js.ts +27 -27
- package/bundle/typescript/src/templates/meteor/config/deploy.sh.template +101 -101
- package/bundle/typescript/src/templates/meteor/config/docker-compose.yaml +17 -17
- package/bundle/typescript/src/templates/meteor/config/nginx.conf.template +31 -31
- package/bundle/typescript/src/templates/meteor/config/pm2.config.js +27 -27
- package/bundle/typescript/src/templates/meteor/config/process.env +5 -5
- package/bundle/typescript/src/templates/meteor/config/settings.json +11 -11
- package/bundle/typescript/src/templates/meteor/config/ssh.json +6 -6
- package/bundle/typescript/src/templates/meteor/dbc/config.js +70 -70
- package/bundle/typescript/src/templates/meteor/dbc/config.js.ts +70 -70
- package/bundle/typescript/src/templates/meteor/dbc/conn.js +37 -37
- package/bundle/typescript/src/templates/meteor/dbc/conn.js.ts +37 -37
- package/bundle/typescript/src/templates/meteor/dbc/register-dbc.js +3 -3
- package/bundle/typescript/src/templates/meteor/dbc/register-dbc.js.ts +3 -3
- package/bundle/typescript/src/templates/meteor/github/workflows/deploy.yaml +150 -150
- package/bundle/typescript/src/templates/meteor/method/method.js +48 -48
- package/bundle/typescript/src/templates/meteor/method/method.js.ts +48 -48
- package/bundle/typescript/src/templates/meteor/package/package.js +37 -37
- package/bundle/typescript/src/templates/meteor/package/package.js.jsx +37 -37
- package/bundle/typescript/src/templates/meteor/package/package.js.ts +36 -36
- package/bundle/typescript/src/templates/meteor/package/package.js.tsx +37 -37
- package/bundle/typescript/src/templates/meteor/package/tests/client/package.js +5 -5
- package/bundle/typescript/src/templates/meteor/package/tests/client/package.js.jsx +5 -5
- package/bundle/typescript/src/templates/meteor/package/tests/client/package.js.ts +5 -5
- package/bundle/typescript/src/templates/meteor/package/tests/client/package.js.tsx +5 -5
- package/bundle/typescript/src/templates/meteor/package/tests/server/package.js +5 -5
- package/bundle/typescript/src/templates/meteor/package/tests/server/package.js.jsx +5 -5
- package/bundle/typescript/src/templates/meteor/package/tests/server/package.js.ts +5 -5
- package/bundle/typescript/src/templates/meteor/package/tests/server/package.js.tsx +5 -5
- package/bundle/typescript/src/templates/meteor/project/.maka/config.json +29 -29
- package/bundle/typescript/src/templates/meteor/project/README.md +33 -33
- package/bundle/typescript/src/templates/meteor/project/build/README +4 -4
- package/bundle/typescript/src/templates/meteor/project/gitignore +10 -10
- package/bundle/typescript/src/templates/meteor/project/package.json +29 -29
- package/bundle/typescript/src/templates/meteor/publish/publish.js +7 -7
- package/bundle/typescript/src/templates/meteor/publish/publish.js.ts +7 -7
- package/bundle/typescript/src/templates/meteor/service/logger/logger.js +27 -27
- package/bundle/typescript/src/templates/meteor/service/logger/logger.js.ts +27 -27
- package/bundle/typescript/src/templates/meteor/stylesheet/stylesheet.css +5 -5
- package/bundle/typescript/src/templates/meteor/stylesheet/stylesheet.css.less +5 -5
- package/bundle/typescript/src/templates/meteor/template/template-tests.js +1 -1
- package/bundle/typescript/src/templates/meteor/template/template-tests.js.jsx +55 -55
- package/bundle/typescript/src/templates/meteor/template/template-tests.js.ts +1 -1
- package/bundle/typescript/src/templates/meteor/template/template-tests.js.tsx +55 -55
- package/bundle/typescript/src/templates/meteor/template/template.css +3 -3
- package/bundle/typescript/src/templates/meteor/template/template.css.less +3 -3
- package/bundle/typescript/src/templates/meteor/template/template.css.scss +3 -3
- package/bundle/typescript/src/templates/meteor/template/template.html +5 -5
- package/bundle/typescript/src/templates/meteor/template/template.js +20 -20
- package/bundle/typescript/src/templates/meteor/template/template.js.jsx +77 -77
- package/bundle/typescript/src/templates/meteor/template/template.js.ts +1 -1
- package/bundle/typescript/src/templates/meteor/template/template.js.tsx +89 -89
- package/bundle/typescript/src/templates/react/component/component.css +6 -6
- package/bundle/typescript/src/templates/react/component/component.css.less +6 -6
- package/bundle/typescript/src/templates/react/component/component.css.scss +3 -3
- package/bundle/typescript/src/templates/react/component/component.js.jsx +59 -59
- package/bundle/typescript/src/templates/react/component/component.js.tsx +65 -65
- package/bundle/typescript/src/templates/react/hook/hook.css +3 -3
- package/bundle/typescript/src/templates/react/hook/hook.css.scss +3 -3
- package/bundle/typescript/src/templates/react/hook/hook.js.jsx +19 -19
- package/bundle/typescript/src/templates/react/hook/hook.js.tsx +19 -19
- package/bundle/typescript/src/templates/react/kit/auth/provider/authentication-provider.js.jsx +306 -306
- package/bundle/typescript/src/templates/react/kit/auth/provider/authentication-provider.js.tsx +350 -350
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-client.js.jsx +178 -178
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-client.js.tsx +178 -178
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-config.js.jsx +59 -59
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-config.js.tsx +67 -67
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-methods.js.jsx +273 -273
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-methods.js.tsx +275 -275
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-validator.js.jsx +182 -182
- package/bundle/typescript/src/templates/react/kit/auth/service/auth0-validator.js.tsx +199 -199
- package/bundle/typescript/src/templates/react/kit/auth/service/meteor-auth-service.js.jsx +138 -138
- package/bundle/typescript/src/templates/react/kit/auth/service/meteor-auth-service.js.tsx +153 -153
- package/bundle/typescript/src/templates/react/kit/esri/map/basic-map.js.jsx +29 -29
- package/bundle/typescript/src/templates/react/kit/esri/map/basic-map.js.tsx +32 -32
- package/bundle/typescript/src/templates/react/kit/frames/frames-demo.css +63 -63
- package/bundle/typescript/src/templates/react/kit/frames/frames-demo.jsx +153 -153
- package/bundle/typescript/src/templates/react/kit/frames/frames-demo.tsx +164 -164
- package/bundle/typescript/src/templates/react/kit/frames/workspace-manager.css +105 -105
- package/bundle/typescript/src/templates/react/kit/frames/workspace-manager.jsx +158 -158
- package/bundle/typescript/src/templates/react/kit/frames/workspace-manager.tsx +166 -166
- package/bundle/typescript/src/templates/react/kit/mui/auth/forgot-password/basic-forgot-password-page.js.jsx +34 -34
- package/bundle/typescript/src/templates/react/kit/mui/auth/forgot-password/basic-forgot-password-page.js.tsx +33 -33
- package/bundle/typescript/src/templates/react/kit/mui/auth/login/basic-login-page.js.jsx +53 -53
- package/bundle/typescript/src/templates/react/kit/mui/auth/login/basic-login-page.js.tsx +53 -53
- package/bundle/typescript/src/templates/react/kit/mui/auth/logout/basic-logout-page.js.jsx +25 -25
- package/bundle/typescript/src/templates/react/kit/mui/auth/logout/basic-logout-page.js.tsx +25 -25
- package/bundle/typescript/src/templates/react/kit/mui/auth/password-reset/basic-password-reset-page.js.jsx +41 -41
- package/bundle/typescript/src/templates/react/kit/mui/auth/password-reset/basic-password-reset-page.js.tsx +34 -34
- package/bundle/typescript/src/templates/react/kit/mui/auth/register/basic-register-page.js.jsx +33 -33
- package/bundle/typescript/src/templates/react/kit/mui/auth/register/basic-register-page.js.tsx +33 -33
- package/bundle/typescript/src/templates/react/kit/mui/auth0/auth-callback.js.jsx +71 -71
- package/bundle/typescript/src/templates/react/kit/mui/auth0/auth-callback.js.tsx +71 -71
- package/bundle/typescript/src/templates/react/kit/mui/auth0/auth0-account-settings.js.jsx +123 -123
- package/bundle/typescript/src/templates/react/kit/mui/auth0/auth0-account-settings.js.tsx +123 -123
- package/bundle/typescript/src/templates/react/kit/mui/auth0/auth0-login-button.js.jsx +56 -56
- package/bundle/typescript/src/templates/react/kit/mui/auth0/auth0-login-button.js.tsx +74 -74
- package/bundle/typescript/src/templates/react/kit/mui/frame/app-bars/basic-app-bar.js.jsx +43 -43
- package/bundle/typescript/src/templates/react/kit/mui/frame/app-bars/basic-app-bar.js.tsx +43 -43
- package/bundle/typescript/src/templates/react/kit/mui/frame/drawers/basic-drawer.js.jsx +121 -121
- package/bundle/typescript/src/templates/react/kit/mui/frame/drawers/basic-drawer.js.tsx +117 -117
- package/bundle/typescript/src/templates/react/kit/mui/frame/footers/basic-sticky-footer.js.jsx +41 -41
- package/bundle/typescript/src/templates/react/kit/mui/frame/footers/basic-sticky-footer.js.tsx +41 -41
- package/bundle/typescript/src/templates/react/route/route.js +8 -8
- package/bundle/typescript/src/templates/react/route/route.js.jsx +5 -5
- package/bundle/typescript/src/templates/react/route/route.js.ts +8 -8
- package/bundle/typescript/src/templates/react/route/route.js.tsx +5 -5
- package/bundle/typescript/src/templates/react/test/test.js +1 -1
- package/bundle/typescript/src/templates/react/test/test.js.jsx +40 -40
- package/bundle/typescript/src/templates/react/test/test.js.ts +1 -1
- package/bundle/typescript/src/templates/react/test/test.js.tsx +40 -40
- package/bundle/typescript/src/templates/service/docker/Dockerfile +54 -54
- package/bundle/typescript/src/templates/service/eslint/babel.config.js +16 -16
- package/bundle/typescript/src/templates/service/eslint/config.eslint.js +69 -69
- package/bundle/typescript/src/templates/service/i18n/i18n.js +33 -33
- package/bundle/typescript/src/templates/service/i18n/i18n.js.ts +33 -33
- package/bundle/typescript/src/templates/service/i18n/locales.js +3 -3
- package/bundle/typescript/src/templates/service/i18n/locales.js.ts +3 -3
- package/bundle/typescript/src/templates/service/openssl/openssl.conf +22 -22
- package/bundle/typescript/src/templates/service/test/jest/jest.config.js +24 -24
- package/bundle/typescript/src/templates/service/test/jest/jest.setup.js +7 -7
- package/bundle/typescript/src/tool.d.ts +2 -0
- package/bundle/typescript/src/tool.js +5 -2
- package/bundle/typescript/src/tool.js.map +1 -1
- package/package.json +120 -120
|
@@ -21,14 +21,14 @@ Generator.create({
|
|
|
21
21
|
requiredEngines: {
|
|
22
22
|
client: ClientEngines.REACT,
|
|
23
23
|
},
|
|
24
|
-
description: `
|
|
25
|
-
This kit generates an Auth0 authentication integration for your Meteor application.
|
|
26
|
-
|
|
27
|
-
It includes:
|
|
28
|
-
- Auth0 client SDK configuration
|
|
29
|
-
- Server-side JWT token validation with JWKS
|
|
30
|
-
- Account linking between Auth0 and Meteor
|
|
31
|
-
- Seamless integration with existing authentication provider
|
|
24
|
+
description: `
|
|
25
|
+
This kit generates an Auth0 authentication integration for your Meteor application.
|
|
26
|
+
|
|
27
|
+
It includes:
|
|
28
|
+
- Auth0 client SDK configuration
|
|
29
|
+
- Server-side JWT token validation with JWKS
|
|
30
|
+
- Account linking between Auth0 and Meteor
|
|
31
|
+
- Seamless integration with existing authentication provider
|
|
32
32
|
`
|
|
33
33
|
}, async function (args, opts) {
|
|
34
34
|
const { fsi, pkg, scaffold, projectConfig } = this;
|
|
@@ -142,159 +142,159 @@ Generator.create({
|
|
|
142
142
|
// Import Auth0 client functions
|
|
143
143
|
await scaffold.injectAtBeginningOfFile({
|
|
144
144
|
filePath: `${pathToAuthService}.${jsEngine}`,
|
|
145
|
-
content: `import {
|
|
146
|
-
loginWithAuth0Redirect,
|
|
147
|
-
loginWithAuth0Popup,
|
|
148
|
-
handleAuth0Callback,
|
|
149
|
-
logoutAuth0,
|
|
150
|
-
getAuth0IdToken,
|
|
151
|
-
getAuth0AccessToken,
|
|
152
|
-
refreshAuth0Token,
|
|
153
|
-
} from './auth0-client';
|
|
145
|
+
content: `import {
|
|
146
|
+
loginWithAuth0Redirect,
|
|
147
|
+
loginWithAuth0Popup,
|
|
148
|
+
handleAuth0Callback,
|
|
149
|
+
logoutAuth0,
|
|
150
|
+
getAuth0IdToken,
|
|
151
|
+
getAuth0AccessToken,
|
|
152
|
+
refreshAuth0Token,
|
|
153
|
+
} from './auth0-client';
|
|
154
154
|
`
|
|
155
155
|
});
|
|
156
156
|
// Add Auth0 methods to AuthService class
|
|
157
|
-
const auth0Methods = `
|
|
158
|
-
// ============================================================================
|
|
159
|
-
// Auth0 Authentication Methods
|
|
160
|
-
// ============================================================================
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Login with Auth0 using redirect flow
|
|
164
|
-
* User will be redirected to Auth0 login page
|
|
165
|
-
*/
|
|
166
|
-
static async loginWithAuth0Redirect() {
|
|
167
|
-
try {
|
|
168
|
-
await loginWithAuth0Redirect();
|
|
169
|
-
} catch (error) {
|
|
170
|
-
console.error('Auth0 redirect login failed:', error);
|
|
171
|
-
throw error;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Login with Auth0 using popup flow
|
|
177
|
-
* Returns the authenticated Meteor user
|
|
178
|
-
*/
|
|
179
|
-
static async loginWithAuth0Popup() {
|
|
180
|
-
try {
|
|
181
|
-
// Open Auth0 login popup and get tokens
|
|
182
|
-
const { idToken, accessToken } = await loginWithAuth0Popup();
|
|
183
|
-
|
|
184
|
-
// Call Meteor method to validate token and create/link user
|
|
185
|
-
const result = await Meteor.callAsync('auth0.login', idToken, accessToken);
|
|
186
|
-
|
|
187
|
-
// Login to Meteor with the generated token
|
|
188
|
-
return new Promise((resolve, reject) => {
|
|
189
|
-
Meteor.loginWithToken(result.token, (error) => {
|
|
190
|
-
if (error) {
|
|
191
|
-
reject(error);
|
|
192
|
-
} else {
|
|
193
|
-
resolve(Meteor.user());
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
} catch (error) {
|
|
198
|
-
console.error('Auth0 popup login failed:', error);
|
|
199
|
-
throw error;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Handle Auth0 callback after redirect
|
|
205
|
-
* Call this method on your callback page
|
|
206
|
-
*/
|
|
207
|
-
static async handleAuth0Callback() {
|
|
208
|
-
try {
|
|
209
|
-
// Handle the redirect and get tokens
|
|
210
|
-
const { idToken, accessToken } = await handleAuth0Callback();
|
|
211
|
-
|
|
212
|
-
// Call Meteor method to validate token and create/link user
|
|
213
|
-
const result = await Meteor.callAsync('auth0.login', idToken, accessToken);
|
|
214
|
-
|
|
215
|
-
// Login to Meteor with the generated token
|
|
216
|
-
return new Promise((resolve, reject) => {
|
|
217
|
-
Meteor.loginWithToken(result.token, (error) => {
|
|
218
|
-
if (error) {
|
|
219
|
-
reject(error);
|
|
220
|
-
} else {
|
|
221
|
-
resolve(Meteor.user());
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
} catch (error) {
|
|
226
|
-
console.error('Auth0 callback handling failed:', error);
|
|
227
|
-
throw error;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Link Auth0 account to currently logged in Meteor user
|
|
233
|
-
*/
|
|
234
|
-
static async linkAuth0Account() {
|
|
235
|
-
try {
|
|
236
|
-
// Get current Auth0 tokens
|
|
237
|
-
const idToken = await getAuth0IdToken();
|
|
238
|
-
const accessToken = await getAuth0AccessToken();
|
|
239
|
-
|
|
240
|
-
// Call Meteor method to link accounts
|
|
241
|
-
await Meteor.callAsync('auth0.linkAccount', idToken, accessToken);
|
|
242
|
-
|
|
243
|
-
return true;
|
|
244
|
-
} catch (error) {
|
|
245
|
-
console.error('Auth0 account linking failed:', error);
|
|
246
|
-
throw error;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Unlink Auth0 account from current user
|
|
252
|
-
*/
|
|
253
|
-
static async unlinkAuth0Account() {
|
|
254
|
-
try {
|
|
255
|
-
await Meteor.callAsync('auth0.unlinkAccount');
|
|
256
|
-
return true;
|
|
257
|
-
} catch (error) {
|
|
258
|
-
console.error('Auth0 account unlinking failed:', error);
|
|
259
|
-
throw error;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Logout from both Auth0 and Meteor
|
|
265
|
-
*/
|
|
266
|
-
static async logoutAuth0() {
|
|
267
|
-
try {
|
|
268
|
-
// Logout from Meteor first
|
|
269
|
-
await this.deauthenticateUser();
|
|
270
|
-
|
|
271
|
-
// Then logout from Auth0
|
|
272
|
-
await logoutAuth0();
|
|
273
|
-
} catch (error) {
|
|
274
|
-
console.error('Auth0 logout failed:', error);
|
|
275
|
-
throw error;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Silently refresh the Auth0 token and update Meteor session
|
|
281
|
-
* This is called automatically when the token is about to expire
|
|
282
|
-
* Returns the updated expiry time
|
|
283
|
-
*/
|
|
284
|
-
static async refreshAuth0Token() {
|
|
285
|
-
try {
|
|
286
|
-
// Get fresh tokens from Auth0 silently (using refresh token)
|
|
287
|
-
const { idToken, accessToken } = await refreshAuth0Token();
|
|
288
|
-
|
|
289
|
-
// Call Meteor method to validate and update tokens
|
|
290
|
-
const result = await Meteor.callAsync('auth0.refreshToken', idToken, accessToken);
|
|
291
|
-
|
|
292
|
-
return result;
|
|
293
|
-
} catch (error) {
|
|
294
|
-
console.error('Auth0 token refresh failed:', error);
|
|
295
|
-
throw error;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
157
|
+
const auth0Methods = `
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// Auth0 Authentication Methods
|
|
160
|
+
// ============================================================================
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Login with Auth0 using redirect flow
|
|
164
|
+
* User will be redirected to Auth0 login page
|
|
165
|
+
*/
|
|
166
|
+
static async loginWithAuth0Redirect() {
|
|
167
|
+
try {
|
|
168
|
+
await loginWithAuth0Redirect();
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error('Auth0 redirect login failed:', error);
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Login with Auth0 using popup flow
|
|
177
|
+
* Returns the authenticated Meteor user
|
|
178
|
+
*/
|
|
179
|
+
static async loginWithAuth0Popup() {
|
|
180
|
+
try {
|
|
181
|
+
// Open Auth0 login popup and get tokens
|
|
182
|
+
const { idToken, accessToken } = await loginWithAuth0Popup();
|
|
183
|
+
|
|
184
|
+
// Call Meteor method to validate token and create/link user
|
|
185
|
+
const result = await Meteor.callAsync('auth0.login', idToken, accessToken);
|
|
186
|
+
|
|
187
|
+
// Login to Meteor with the generated token
|
|
188
|
+
return new Promise((resolve, reject) => {
|
|
189
|
+
Meteor.loginWithToken(result.token, (error) => {
|
|
190
|
+
if (error) {
|
|
191
|
+
reject(error);
|
|
192
|
+
} else {
|
|
193
|
+
resolve(Meteor.user());
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error('Auth0 popup login failed:', error);
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Handle Auth0 callback after redirect
|
|
205
|
+
* Call this method on your callback page
|
|
206
|
+
*/
|
|
207
|
+
static async handleAuth0Callback() {
|
|
208
|
+
try {
|
|
209
|
+
// Handle the redirect and get tokens
|
|
210
|
+
const { idToken, accessToken } = await handleAuth0Callback();
|
|
211
|
+
|
|
212
|
+
// Call Meteor method to validate token and create/link user
|
|
213
|
+
const result = await Meteor.callAsync('auth0.login', idToken, accessToken);
|
|
214
|
+
|
|
215
|
+
// Login to Meteor with the generated token
|
|
216
|
+
return new Promise((resolve, reject) => {
|
|
217
|
+
Meteor.loginWithToken(result.token, (error) => {
|
|
218
|
+
if (error) {
|
|
219
|
+
reject(error);
|
|
220
|
+
} else {
|
|
221
|
+
resolve(Meteor.user());
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error('Auth0 callback handling failed:', error);
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Link Auth0 account to currently logged in Meteor user
|
|
233
|
+
*/
|
|
234
|
+
static async linkAuth0Account() {
|
|
235
|
+
try {
|
|
236
|
+
// Get current Auth0 tokens
|
|
237
|
+
const idToken = await getAuth0IdToken();
|
|
238
|
+
const accessToken = await getAuth0AccessToken();
|
|
239
|
+
|
|
240
|
+
// Call Meteor method to link accounts
|
|
241
|
+
await Meteor.callAsync('auth0.linkAccount', idToken, accessToken);
|
|
242
|
+
|
|
243
|
+
return true;
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error('Auth0 account linking failed:', error);
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Unlink Auth0 account from current user
|
|
252
|
+
*/
|
|
253
|
+
static async unlinkAuth0Account() {
|
|
254
|
+
try {
|
|
255
|
+
await Meteor.callAsync('auth0.unlinkAccount');
|
|
256
|
+
return true;
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error('Auth0 account unlinking failed:', error);
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Logout from both Auth0 and Meteor
|
|
265
|
+
*/
|
|
266
|
+
static async logoutAuth0() {
|
|
267
|
+
try {
|
|
268
|
+
// Logout from Meteor first
|
|
269
|
+
await this.deauthenticateUser();
|
|
270
|
+
|
|
271
|
+
// Then logout from Auth0
|
|
272
|
+
await logoutAuth0();
|
|
273
|
+
} catch (error) {
|
|
274
|
+
console.error('Auth0 logout failed:', error);
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Silently refresh the Auth0 token and update Meteor session
|
|
281
|
+
* This is called automatically when the token is about to expire
|
|
282
|
+
* Returns the updated expiry time
|
|
283
|
+
*/
|
|
284
|
+
static async refreshAuth0Token() {
|
|
285
|
+
try {
|
|
286
|
+
// Get fresh tokens from Auth0 silently (using refresh token)
|
|
287
|
+
const { idToken, accessToken } = await refreshAuth0Token();
|
|
288
|
+
|
|
289
|
+
// Call Meteor method to validate and update tokens
|
|
290
|
+
const result = await Meteor.callAsync('auth0.refreshToken', idToken, accessToken);
|
|
291
|
+
|
|
292
|
+
return result;
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error('Auth0 token refresh failed:', error);
|
|
295
|
+
throw error;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
298
|
`;
|
|
299
299
|
await scaffold.injectIntoFile({
|
|
300
300
|
filePath: `${pathToAuthService}.${jsEngine}`,
|
|
@@ -317,14 +317,14 @@ Generator.create({
|
|
|
317
317
|
// Import AuthService if not already imported
|
|
318
318
|
await scaffold.injectAtBeginningOfFile({
|
|
319
319
|
filePath: `${pathToAuthProvider}.${jsEngine}`,
|
|
320
|
-
content: `import AuthService from './authentication-service';
|
|
320
|
+
content: `import AuthService from './authentication-service';
|
|
321
321
|
`
|
|
322
322
|
});
|
|
323
323
|
// Add Auth0 methods to context value
|
|
324
|
-
const auth0ProviderMethods = ` loginWithAuth0Redirect: AuthService.loginWithAuth0Redirect,
|
|
325
|
-
loginWithAuth0Popup: AuthService.loginWithAuth0Popup,
|
|
326
|
-
linkAuth0Account: AuthService.linkAuth0Account,
|
|
327
|
-
unlinkAuth0Account: AuthService.unlinkAuth0Account,
|
|
324
|
+
const auth0ProviderMethods = ` loginWithAuth0Redirect: AuthService.loginWithAuth0Redirect,
|
|
325
|
+
loginWithAuth0Popup: AuthService.loginWithAuth0Popup,
|
|
326
|
+
linkAuth0Account: AuthService.linkAuth0Account,
|
|
327
|
+
unlinkAuth0Account: AuthService.unlinkAuth0Account,
|
|
328
328
|
`;
|
|
329
329
|
await scaffold.injectIntoFile({
|
|
330
330
|
filePath: `${pathToAuthProvider}.${jsEngine}`,
|
|
@@ -339,149 +339,149 @@ Generator.create({
|
|
|
339
339
|
// Replace placeholder auth functions with AuthService delegations
|
|
340
340
|
authProviderContent = authProviderContent
|
|
341
341
|
// Replace authenticateUser function
|
|
342
|
-
.replace(/const authenticateUser = async \(username[^}]*\{[\s\S]*?throw new Error\('Invalid credentials'\);[\s\S]*?\};/, `const authenticateUser = async (username, password) => {
|
|
343
|
-
return AuthService.authenticateUser(username, password);
|
|
342
|
+
.replace(/const authenticateUser = async \(username[^}]*\{[\s\S]*?throw new Error\('Invalid credentials'\);[\s\S]*?\};/, `const authenticateUser = async (username, password) => {
|
|
343
|
+
return AuthService.authenticateUser(username, password);
|
|
344
344
|
};`)
|
|
345
345
|
// Replace authenticateToken function
|
|
346
|
-
.replace(/const authenticateToken = async \(\)[^}]*\{[\s\S]*?throw new Error\('Invalid token'\);[\s\S]*?\};/, `const authenticateToken = async () => {
|
|
347
|
-
return AuthService.authenticateToken();
|
|
346
|
+
.replace(/const authenticateToken = async \(\)[^}]*\{[\s\S]*?throw new Error\('Invalid token'\);[\s\S]*?\};/, `const authenticateToken = async () => {
|
|
347
|
+
return AuthService.authenticateToken();
|
|
348
348
|
};`)
|
|
349
349
|
// Replace getUserAuthorizations function
|
|
350
|
-
.replace(/const getUserAuthorizations = async \(user[^}]*\{[\s\S]*?return \[\];[\s\S]*?\};/, `const getUserAuthorizations = async (user) => {
|
|
351
|
-
return AuthService.getUserAuthorizations(user?._id);
|
|
350
|
+
.replace(/const getUserAuthorizations = async \(user[^}]*\{[\s\S]*?return \[\];[\s\S]*?\};/, `const getUserAuthorizations = async (user) => {
|
|
351
|
+
return AuthService.getUserAuthorizations(user?._id);
|
|
352
352
|
};`)
|
|
353
353
|
// Replace deauthenticateUser function
|
|
354
|
-
.replace(/const deauthenticateUser = async \(\)[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const deauthenticateUser = async () => {
|
|
355
|
-
return AuthService.deauthenticateUser();
|
|
354
|
+
.replace(/const deauthenticateUser = async \(\)[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const deauthenticateUser = async () => {
|
|
355
|
+
return AuthService.deauthenticateUser();
|
|
356
356
|
};`)
|
|
357
357
|
// Replace sendForgotPasswordEmail function
|
|
358
|
-
.replace(/const sendForgotPasswordEmail = async \(email[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const sendForgotPasswordEmail = async (email) => {
|
|
359
|
-
return AuthService.sendForgotPasswordEmail(email);
|
|
358
|
+
.replace(/const sendForgotPasswordEmail = async \(email[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const sendForgotPasswordEmail = async (email) => {
|
|
359
|
+
return AuthService.sendForgotPasswordEmail(email);
|
|
360
360
|
};`)
|
|
361
361
|
// Replace registerNewUser function
|
|
362
|
-
.replace(/const registerNewUser = async \(email, password[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const registerNewUser = async (email, password) => {
|
|
363
|
-
return AuthService.registerNewUser(email, password);
|
|
362
|
+
.replace(/const registerNewUser = async \(email, password[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const registerNewUser = async (email, password) => {
|
|
363
|
+
return AuthService.registerNewUser(email, password);
|
|
364
364
|
};`)
|
|
365
365
|
// Replace resetPasswordWithToken function
|
|
366
|
-
.replace(/const resetPasswordWithToken = async \(token, password[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const resetPasswordWithToken = async (token, password) => {
|
|
367
|
-
return AuthService.resetPasswordWithToken(token, password);
|
|
366
|
+
.replace(/const resetPasswordWithToken = async \(token, password[^}]*\{[\s\S]*?return true;[\s\S]*?\};/, `const resetPasswordWithToken = async (token, password) => {
|
|
367
|
+
return AuthService.resetPasswordWithToken(token, password);
|
|
368
368
|
};`);
|
|
369
369
|
fs.writeFileSync(authProviderFilePath, authProviderContent, 'utf8');
|
|
370
370
|
// Add automatic Auth0 token refresh monitoring
|
|
371
|
-
const auth0TokenRefreshHook = jsEngine === 'tsx' ? `
|
|
372
|
-
// Auth0 automatic token refresh
|
|
373
|
-
// This hook monitors the Auth0 token expiration and refreshes it 15 seconds before expiry
|
|
374
|
-
useEffect(() => {
|
|
375
|
-
if (!currentUser) return;
|
|
376
|
-
|
|
377
|
-
let refreshTimer: NodeJS.Timeout;
|
|
378
|
-
|
|
379
|
-
const scheduleTokenRefresh = async () => {
|
|
380
|
-
try {
|
|
381
|
-
// Check if user has Auth0 account linked
|
|
382
|
-
const user = Meteor.user();
|
|
383
|
-
if (!user?.services?.auth0) return;
|
|
384
|
-
|
|
385
|
-
// Get token expiry from server
|
|
386
|
-
const tokenInfo = await Meteor.callAsync('auth0.checkTokenValidity');
|
|
387
|
-
|
|
388
|
-
if (!tokenInfo.isValid) {
|
|
389
|
-
// Token already expired, refresh immediately
|
|
390
|
-
await AuthService.refreshAuth0Token();
|
|
391
|
-
scheduleTokenRefresh(); // Schedule next refresh
|
|
392
|
-
} else if (tokenInfo.expiresAt) {
|
|
393
|
-
// Calculate time until 15 seconds before expiry
|
|
394
|
-
const expiresAt = new Date(tokenInfo.expiresAt).getTime();
|
|
395
|
-
const now = Date.now();
|
|
396
|
-
const refreshIn = expiresAt - now - 15000; // Refresh 15 seconds before expiry
|
|
397
|
-
|
|
398
|
-
if (refreshIn > 0) {
|
|
399
|
-
// Schedule refresh
|
|
400
|
-
refreshTimer = setTimeout(async () => {
|
|
401
|
-
try {
|
|
402
|
-
await AuthService.refreshAuth0Token();
|
|
403
|
-
scheduleTokenRefresh(); // Schedule next refresh after successful refresh
|
|
404
|
-
} catch (error) {
|
|
405
|
-
console.error('Failed to refresh Auth0 token:', error);
|
|
406
|
-
// If refresh fails, user will be logged out when token expires
|
|
407
|
-
}
|
|
408
|
-
}, refreshIn);
|
|
409
|
-
} else {
|
|
410
|
-
// Less than 15 seconds until expiry, refresh now
|
|
411
|
-
await AuthService.refreshAuth0Token();
|
|
412
|
-
scheduleTokenRefresh();
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
} catch (error) {
|
|
416
|
-
console.error('Error scheduling token refresh:', error);
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
|
|
420
|
-
scheduleTokenRefresh();
|
|
421
|
-
|
|
422
|
-
return () => {
|
|
423
|
-
if (refreshTimer) {
|
|
424
|
-
clearTimeout(refreshTimer);
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
}, [currentUser]);
|
|
428
|
-
` : `
|
|
429
|
-
// Auth0 automatic token refresh
|
|
430
|
-
// This hook monitors the Auth0 token expiration and refreshes it 15 seconds before expiry
|
|
431
|
-
useEffect(() => {
|
|
432
|
-
if (!currentUser) return;
|
|
433
|
-
|
|
434
|
-
let refreshTimer;
|
|
435
|
-
|
|
436
|
-
const scheduleTokenRefresh = async () => {
|
|
437
|
-
try {
|
|
438
|
-
// Check if user has Auth0 account linked
|
|
439
|
-
const user = Meteor.user();
|
|
440
|
-
if (!user?.services?.auth0) return;
|
|
441
|
-
|
|
442
|
-
// Get token expiry from server
|
|
443
|
-
const tokenInfo = await Meteor.callAsync('auth0.checkTokenValidity');
|
|
444
|
-
|
|
445
|
-
if (!tokenInfo.isValid) {
|
|
446
|
-
// Token already expired, refresh immediately
|
|
447
|
-
await AuthService.refreshAuth0Token();
|
|
448
|
-
scheduleTokenRefresh(); // Schedule next refresh
|
|
449
|
-
} else if (tokenInfo.expiresAt) {
|
|
450
|
-
// Calculate time until 15 seconds before expiry
|
|
451
|
-
const expiresAt = new Date(tokenInfo.expiresAt).getTime();
|
|
452
|
-
const now = Date.now();
|
|
453
|
-
const refreshIn = expiresAt - now - 15000; // Refresh 15 seconds before expiry
|
|
454
|
-
|
|
455
|
-
if (refreshIn > 0) {
|
|
456
|
-
// Schedule refresh
|
|
457
|
-
refreshTimer = setTimeout(async () => {
|
|
458
|
-
try {
|
|
459
|
-
await AuthService.refreshAuth0Token();
|
|
460
|
-
scheduleTokenRefresh(); // Schedule next refresh after successful refresh
|
|
461
|
-
} catch (error) {
|
|
462
|
-
console.error('Failed to refresh Auth0 token:', error);
|
|
463
|
-
// If refresh fails, user will be logged out when token expires
|
|
464
|
-
}
|
|
465
|
-
}, refreshIn);
|
|
466
|
-
} else {
|
|
467
|
-
// Less than 15 seconds until expiry, refresh now
|
|
468
|
-
await AuthService.refreshAuth0Token();
|
|
469
|
-
scheduleTokenRefresh();
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
} catch (error) {
|
|
473
|
-
console.error('Error scheduling token refresh:', error);
|
|
474
|
-
}
|
|
475
|
-
};
|
|
476
|
-
|
|
477
|
-
scheduleTokenRefresh();
|
|
478
|
-
|
|
479
|
-
return () => {
|
|
480
|
-
if (refreshTimer) {
|
|
481
|
-
clearTimeout(refreshTimer);
|
|
482
|
-
}
|
|
483
|
-
};
|
|
484
|
-
}, [currentUser]);
|
|
371
|
+
const auth0TokenRefreshHook = jsEngine === 'tsx' ? `
|
|
372
|
+
// Auth0 automatic token refresh
|
|
373
|
+
// This hook monitors the Auth0 token expiration and refreshes it 15 seconds before expiry
|
|
374
|
+
useEffect(() => {
|
|
375
|
+
if (!currentUser) return;
|
|
376
|
+
|
|
377
|
+
let refreshTimer: NodeJS.Timeout;
|
|
378
|
+
|
|
379
|
+
const scheduleTokenRefresh = async () => {
|
|
380
|
+
try {
|
|
381
|
+
// Check if user has Auth0 account linked
|
|
382
|
+
const user = Meteor.user();
|
|
383
|
+
if (!user?.services?.auth0) return;
|
|
384
|
+
|
|
385
|
+
// Get token expiry from server
|
|
386
|
+
const tokenInfo = await Meteor.callAsync('auth0.checkTokenValidity');
|
|
387
|
+
|
|
388
|
+
if (!tokenInfo.isValid) {
|
|
389
|
+
// Token already expired, refresh immediately
|
|
390
|
+
await AuthService.refreshAuth0Token();
|
|
391
|
+
scheduleTokenRefresh(); // Schedule next refresh
|
|
392
|
+
} else if (tokenInfo.expiresAt) {
|
|
393
|
+
// Calculate time until 15 seconds before expiry
|
|
394
|
+
const expiresAt = new Date(tokenInfo.expiresAt).getTime();
|
|
395
|
+
const now = Date.now();
|
|
396
|
+
const refreshIn = expiresAt - now - 15000; // Refresh 15 seconds before expiry
|
|
397
|
+
|
|
398
|
+
if (refreshIn > 0) {
|
|
399
|
+
// Schedule refresh
|
|
400
|
+
refreshTimer = setTimeout(async () => {
|
|
401
|
+
try {
|
|
402
|
+
await AuthService.refreshAuth0Token();
|
|
403
|
+
scheduleTokenRefresh(); // Schedule next refresh after successful refresh
|
|
404
|
+
} catch (error) {
|
|
405
|
+
console.error('Failed to refresh Auth0 token:', error);
|
|
406
|
+
// If refresh fails, user will be logged out when token expires
|
|
407
|
+
}
|
|
408
|
+
}, refreshIn);
|
|
409
|
+
} else {
|
|
410
|
+
// Less than 15 seconds until expiry, refresh now
|
|
411
|
+
await AuthService.refreshAuth0Token();
|
|
412
|
+
scheduleTokenRefresh();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
} catch (error) {
|
|
416
|
+
console.error('Error scheduling token refresh:', error);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
scheduleTokenRefresh();
|
|
421
|
+
|
|
422
|
+
return () => {
|
|
423
|
+
if (refreshTimer) {
|
|
424
|
+
clearTimeout(refreshTimer);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
}, [currentUser]);
|
|
428
|
+
` : `
|
|
429
|
+
// Auth0 automatic token refresh
|
|
430
|
+
// This hook monitors the Auth0 token expiration and refreshes it 15 seconds before expiry
|
|
431
|
+
useEffect(() => {
|
|
432
|
+
if (!currentUser) return;
|
|
433
|
+
|
|
434
|
+
let refreshTimer;
|
|
435
|
+
|
|
436
|
+
const scheduleTokenRefresh = async () => {
|
|
437
|
+
try {
|
|
438
|
+
// Check if user has Auth0 account linked
|
|
439
|
+
const user = Meteor.user();
|
|
440
|
+
if (!user?.services?.auth0) return;
|
|
441
|
+
|
|
442
|
+
// Get token expiry from server
|
|
443
|
+
const tokenInfo = await Meteor.callAsync('auth0.checkTokenValidity');
|
|
444
|
+
|
|
445
|
+
if (!tokenInfo.isValid) {
|
|
446
|
+
// Token already expired, refresh immediately
|
|
447
|
+
await AuthService.refreshAuth0Token();
|
|
448
|
+
scheduleTokenRefresh(); // Schedule next refresh
|
|
449
|
+
} else if (tokenInfo.expiresAt) {
|
|
450
|
+
// Calculate time until 15 seconds before expiry
|
|
451
|
+
const expiresAt = new Date(tokenInfo.expiresAt).getTime();
|
|
452
|
+
const now = Date.now();
|
|
453
|
+
const refreshIn = expiresAt - now - 15000; // Refresh 15 seconds before expiry
|
|
454
|
+
|
|
455
|
+
if (refreshIn > 0) {
|
|
456
|
+
// Schedule refresh
|
|
457
|
+
refreshTimer = setTimeout(async () => {
|
|
458
|
+
try {
|
|
459
|
+
await AuthService.refreshAuth0Token();
|
|
460
|
+
scheduleTokenRefresh(); // Schedule next refresh after successful refresh
|
|
461
|
+
} catch (error) {
|
|
462
|
+
console.error('Failed to refresh Auth0 token:', error);
|
|
463
|
+
// If refresh fails, user will be logged out when token expires
|
|
464
|
+
}
|
|
465
|
+
}, refreshIn);
|
|
466
|
+
} else {
|
|
467
|
+
// Less than 15 seconds until expiry, refresh now
|
|
468
|
+
await AuthService.refreshAuth0Token();
|
|
469
|
+
scheduleTokenRefresh();
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
} catch (error) {
|
|
473
|
+
console.error('Error scheduling token refresh:', error);
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
scheduleTokenRefresh();
|
|
478
|
+
|
|
479
|
+
return () => {
|
|
480
|
+
if (refreshTimer) {
|
|
481
|
+
clearTimeout(refreshTimer);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}, [currentUser]);
|
|
485
485
|
`;
|
|
486
486
|
await scaffold.injectIntoFile({
|
|
487
487
|
filePath: authProviderFilePath,
|
|
@@ -503,7 +503,7 @@ Generator.create({
|
|
|
503
503
|
});
|
|
504
504
|
await scaffold.injectAtEndOfFile({
|
|
505
505
|
filePath: `${serverIndexFilePath}.${jsEngine}`,
|
|
506
|
-
content: `import './methods/auth0-methods';
|
|
506
|
+
content: `import './methods/auth0-methods';
|
|
507
507
|
`
|
|
508
508
|
});
|
|
509
509
|
// ===================================================================================
|
|
@@ -539,15 +539,15 @@ Generator.create({
|
|
|
539
539
|
// 9. Create .env.example file
|
|
540
540
|
// ===================================================================================
|
|
541
541
|
const envExamplePath = path.join(projectDirectory, '.env.auth0.example');
|
|
542
|
-
const envExample = `# Auth0 Configuration
|
|
543
|
-
# Copy this to your settings.json or .env file and fill in your Auth0 credentials
|
|
544
|
-
|
|
545
|
-
AUTH0_DOMAIN=your-domain.auth0.com
|
|
546
|
-
AUTH0_CLIENT_ID=your_client_id
|
|
547
|
-
AUTH0_CLIENT_SECRET=your_client_secret
|
|
548
|
-
AUTH0_AUDIENCE=https://your-domain.auth0.com/api/v2/
|
|
549
|
-
AUTH0_REDIRECT_URI=http://localhost:3000/auth/callback
|
|
550
|
-
AUTH0_SCOPE=openid profile email
|
|
542
|
+
const envExample = `# Auth0 Configuration
|
|
543
|
+
# Copy this to your settings.json or .env file and fill in your Auth0 credentials
|
|
544
|
+
|
|
545
|
+
AUTH0_DOMAIN=your-domain.auth0.com
|
|
546
|
+
AUTH0_CLIENT_ID=your_client_id
|
|
547
|
+
AUTH0_CLIENT_SECRET=your_client_secret
|
|
548
|
+
AUTH0_AUDIENCE=https://your-domain.auth0.com/api/v2/
|
|
549
|
+
AUTH0_REDIRECT_URI=http://localhost:3000/auth/callback
|
|
550
|
+
AUTH0_SCOPE=openid profile email
|
|
551
551
|
`;
|
|
552
552
|
if (!fsi.isFile(envExamplePath) || shouldForce) {
|
|
553
553
|
fsi.writeToFile({
|
|
@@ -559,317 +559,317 @@ AUTH0_SCOPE=openid profile email
|
|
|
559
559
|
// 10. Create README documentation
|
|
560
560
|
// ===================================================================================
|
|
561
561
|
const readmePath = path.join(projectDirectory, 'README.auth0.md');
|
|
562
|
-
const readmeContent = `# Auth0 Authentication Integration
|
|
563
|
-
|
|
564
|
-
This document explains how Auth0 authentication has been integrated into your Meteor application.
|
|
565
|
-
|
|
566
|
-
## Overview
|
|
567
|
-
|
|
568
|
-
This integration provides a complete Auth0 authentication solution that:
|
|
569
|
-
|
|
570
|
-
- ✅ Supports both redirect and popup login flows
|
|
571
|
-
- ✅ Validates JWT tokens server-side using JWKS
|
|
572
|
-
- ✅ Automatically creates or links Meteor user accounts
|
|
573
|
-
- ✅ Allows account linking for existing users
|
|
574
|
-
- ✅ Provides seamless integration with your existing AuthContext
|
|
575
|
-
|
|
576
|
-
## Architecture
|
|
577
|
-
|
|
578
|
-
### Client-Side Components
|
|
579
|
-
|
|
580
|
-
**\`${resourceTopLevelPathLib}/auth0-config.${jsEngine}\`**
|
|
581
|
-
- Centralized Auth0 configuration
|
|
582
|
-
- Reads settings from \`Meteor.settings.public.auth0\`
|
|
583
|
-
- Provides configuration for both client and server
|
|
584
|
-
|
|
585
|
-
**\`${resourceTopLevelPathClient}/auth0-client.${jsEngine}\`**
|
|
586
|
-
- Auth0 SDK wrapper functions
|
|
587
|
-
- Handles login redirects and popups
|
|
588
|
-
- Manages Auth0 client instance
|
|
589
|
-
- Retrieves ID tokens
|
|
590
|
-
|
|
591
|
-
**\`${resourceTopLevelPathClient}/authentication-service.${jsEngine}\`**
|
|
592
|
-
- Extended with Auth0 authentication methods
|
|
593
|
-
- Bridges Auth0 with Meteor accounts
|
|
594
|
-
- Provides static methods for all Auth0 operations
|
|
595
|
-
|
|
596
|
-
**\`${resourceTopLevelPathClient}/authentication-provider.${jsEngine}\`**
|
|
597
|
-
- Context updated with Auth0 methods
|
|
598
|
-
- Makes Auth0 functions available throughout your app
|
|
599
|
-
|
|
600
|
-
### Server-Side Components
|
|
601
|
-
|
|
602
|
-
**\`${resourceTopLevelPathServer}/auth0-validator.${jsEngine}\`**
|
|
603
|
-
- JWT token validation using JWKS
|
|
604
|
-
- Verifies token signature and claims
|
|
605
|
-
- Creates/updates user accounts from Auth0 data
|
|
606
|
-
|
|
607
|
-
**\`${resourceTopLevelPathServer}/methods/auth0-methods.${jsEngine}\`**
|
|
608
|
-
- Meteor methods for Auth0 operations
|
|
609
|
-
- \`auth0.login\` - Authenticates with ID token
|
|
610
|
-
- \`auth0.linkAccount\` - Links Auth0 to existing user
|
|
611
|
-
- \`auth0.unlinkAccount\` - Removes Auth0 link
|
|
612
|
-
|
|
613
|
-
## Setup Instructions
|
|
614
|
-
|
|
615
|
-
### 1. Configure Auth0 Application
|
|
616
|
-
|
|
617
|
-
1. Go to [Auth0 Dashboard](https://manage.auth0.com/)
|
|
618
|
-
2. Create a new application (Single Page Application)
|
|
619
|
-
3. Configure the following settings:
|
|
620
|
-
- **Allowed Callback URLs**: \`http://localhost:3000/auth/callback\`
|
|
621
|
-
- **Allowed Logout URLs**: \`http://localhost:3000\`
|
|
622
|
-
- **Allowed Web Origins**: \`http://localhost:3000\`
|
|
623
|
-
- **Allowed Origins (CORS)**: \`http://localhost:3000\`
|
|
624
|
-
|
|
625
|
-
### 2. Update Configuration
|
|
626
|
-
|
|
627
|
-
Edit \`settings.auth0.json\` with your Auth0 credentials:
|
|
628
|
-
|
|
629
|
-
\`\`\`json
|
|
630
|
-
{
|
|
631
|
-
"public": {
|
|
632
|
-
"auth0": {
|
|
633
|
-
"domain": "your-domain.auth0.com",
|
|
634
|
-
"clientId": "your_client_id",
|
|
635
|
-
"audience": "https://your-domain.auth0.com/api/v2/",
|
|
636
|
-
"redirectUri": "http://localhost:3000/auth/callback",
|
|
637
|
-
"scope": "openid profile email"
|
|
638
|
-
}
|
|
639
|
-
},
|
|
640
|
-
"auth0": {
|
|
641
|
-
"domain": "your-domain.auth0.com",
|
|
642
|
-
"clientId": "your_client_id",
|
|
643
|
-
"clientSecret": "your_client_secret",
|
|
644
|
-
"audience": "https://your-domain.auth0.com/api/v2/",
|
|
645
|
-
"redirectUri": "http://localhost:3000/auth/callback",
|
|
646
|
-
"scope": "openid profile email"
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
\`\`\`
|
|
650
|
-
|
|
651
|
-
### 3. Start Your Application
|
|
652
|
-
|
|
653
|
-
\`\`\`bash
|
|
654
|
-
cd app
|
|
655
|
-
meteor --settings ../settings.auth0.json
|
|
656
|
-
\`\`\`
|
|
657
|
-
|
|
658
|
-
## Usage
|
|
659
|
-
|
|
660
|
-
### Using Auth0 in Components
|
|
661
|
-
|
|
662
|
-
The Auth0 methods are available through the AuthContext:
|
|
663
|
-
|
|
664
|
-
\`\`\`${jsEngine === 'tsx' ? 'typescript' : 'javascript'}
|
|
665
|
-
import React, { useContext } from 'react';
|
|
666
|
-
import { AuthContext } from '${resourceTopLevelPathClient}/authentication-provider';
|
|
667
|
-
|
|
668
|
-
function LoginButton() {
|
|
669
|
-
const auth = useContext(AuthContext);
|
|
670
|
-
|
|
671
|
-
const handleLogin = async () => {
|
|
672
|
-
try {
|
|
673
|
-
// Option 1: Redirect flow (recommended)
|
|
674
|
-
await auth.loginWithAuth0Redirect?.();
|
|
675
|
-
|
|
676
|
-
// Option 2: Popup flow
|
|
677
|
-
// const user = await auth.loginWithAuth0Popup?.();
|
|
678
|
-
// console.log('Logged in user:', user);
|
|
679
|
-
} catch (error) {
|
|
680
|
-
console.error('Login failed:', error);
|
|
681
|
-
}
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
return <button onClick={handleLogin}>Login with Auth0</button>;
|
|
685
|
-
}
|
|
686
|
-
\`\`\`
|
|
687
|
-
|
|
688
|
-
### Using AuthService Directly
|
|
689
|
-
|
|
690
|
-
You can also use the AuthService static methods:
|
|
691
|
-
|
|
692
|
-
\`\`\`${jsEngine === 'tsx' ? 'typescript' : 'javascript'}
|
|
693
|
-
import AuthService from '${resourceTopLevelPathClient}/authentication-service';
|
|
694
|
-
|
|
695
|
-
// Redirect login
|
|
696
|
-
await AuthService.loginWithAuth0Redirect();
|
|
697
|
-
|
|
698
|
-
// Popup login
|
|
699
|
-
const user = await AuthService.loginWithAuth0Popup();
|
|
700
|
-
|
|
701
|
-
// Handle callback (use in callback page)
|
|
702
|
-
const user = await AuthService.handleAuth0Callback();
|
|
703
|
-
|
|
704
|
-
// Link Auth0 to logged-in user
|
|
705
|
-
await AuthService.linkAuth0Account();
|
|
706
|
-
|
|
707
|
-
// Unlink Auth0 account
|
|
708
|
-
await AuthService.unlinkAuth0Account();
|
|
709
|
-
|
|
710
|
-
// Logout from both Auth0 and Meteor
|
|
711
|
-
await AuthService.logoutAuth0();
|
|
712
|
-
\`\`\`
|
|
713
|
-
|
|
714
|
-
## Authentication Flow
|
|
715
|
-
|
|
716
|
-
### Redirect Flow
|
|
717
|
-
|
|
718
|
-
1. User clicks login button
|
|
719
|
-
2. \`loginWithAuth0Redirect()\` redirects to Auth0 login page
|
|
720
|
-
3. User authenticates with Auth0
|
|
721
|
-
4. Auth0 redirects back to \`/auth/callback\`
|
|
722
|
-
5. Callback page calls \`handleAuth0Callback()\`
|
|
723
|
-
6. Server validates JWT and creates/links Meteor user
|
|
724
|
-
7. User is logged into Meteor and redirected to home page
|
|
725
|
-
|
|
726
|
-
### Popup Flow
|
|
727
|
-
|
|
728
|
-
1. User clicks login button
|
|
729
|
-
2. \`loginWithAuth0Popup()\` opens Auth0 login in popup
|
|
730
|
-
3. User authenticates with Auth0
|
|
731
|
-
4. Popup closes and ID token is returned
|
|
732
|
-
5. Server validates JWT and creates/links Meteor user
|
|
733
|
-
6. User is logged into Meteor
|
|
734
|
-
7. Component receives user object
|
|
735
|
-
|
|
736
|
-
## Account Linking
|
|
737
|
-
|
|
738
|
-
Users can link their Auth0 account to an existing Meteor account:
|
|
739
|
-
|
|
740
|
-
\`\`\`${jsEngine === 'tsx' ? 'typescript' : 'javascript'}
|
|
741
|
-
// User must be logged in first
|
|
742
|
-
const auth = useContext(AuthContext);
|
|
743
|
-
await auth.linkAuth0Account?.();
|
|
744
|
-
\`\`\`
|
|
745
|
-
|
|
746
|
-
This allows users to:
|
|
747
|
-
- Login with either Meteor credentials or Auth0
|
|
748
|
-
- Maintain a single user account with multiple login methods
|
|
749
|
-
- Unlink Auth0 if they no longer want to use it
|
|
750
|
-
|
|
751
|
-
## User Data Structure
|
|
752
|
-
|
|
753
|
-
When a user logs in with Auth0, their Meteor user document includes:
|
|
754
|
-
|
|
755
|
-
\`\`\`javascript
|
|
756
|
-
{
|
|
757
|
-
_id: "userId",
|
|
758
|
-
emails: [{ address: "user@example.com", verified: true }],
|
|
759
|
-
profile: { name: "John Doe" },
|
|
760
|
-
services: {
|
|
761
|
-
auth0: {
|
|
762
|
-
id: "auth0|123456789",
|
|
763
|
-
email: "user@example.com",
|
|
764
|
-
name: "John Doe",
|
|
765
|
-
picture: "https://...",
|
|
766
|
-
email_verified: true
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
\`\`\`
|
|
771
|
-
|
|
772
|
-
## Security Features
|
|
773
|
-
|
|
774
|
-
- **JWT Validation**: Tokens are verified using Auth0's JWKS endpoint
|
|
775
|
-
- **Token Expiration**: Tokens are checked for expiration
|
|
776
|
-
- **Issuer Verification**: Ensures tokens come from your Auth0 domain
|
|
777
|
-
- **Audience Verification**: Validates tokens are for your application
|
|
778
|
-
- **Account Linking Protection**: Prevents duplicate account linking
|
|
779
|
-
|
|
780
|
-
## Troubleshooting
|
|
781
|
-
|
|
782
|
-
### "Login failed: Invalid token" Error After Successful Login
|
|
783
|
-
|
|
784
|
-
If you see this error message even though you're logged in, it's because the placeholder token validation code is still running. The Auth0 kit automatically comments out this code, but if you see this error:
|
|
785
|
-
|
|
786
|
-
1. Check your \`authentication-provider.${jsEngine}\` file
|
|
787
|
-
2. Look for the \`loginUserWithToken\` call in the \`useEffect\` hook
|
|
788
|
-
3. Ensure it's commented out (the generator does this automatically)
|
|
789
|
-
4. Meteor's authentication system handles token validation automatically
|
|
790
|
-
|
|
791
|
-
### "Invalid token" Error During Login
|
|
792
|
-
|
|
793
|
-
- Check that your Auth0 domain and clientId are correct
|
|
794
|
-
- Verify the token hasn't expired
|
|
795
|
-
- Ensure your Auth0 application settings are configured correctly
|
|
796
|
-
- Make sure the domain in settings.json doesn't include \`https://\` (the kit handles this automatically)
|
|
797
|
-
|
|
798
|
-
### "Auth0 configuration missing" Error
|
|
799
|
-
|
|
800
|
-
- Make sure you're starting Meteor with \`--settings ../settings.auth0.json\`
|
|
801
|
-
- Verify the settings file contains all required Auth0 configuration
|
|
802
|
-
|
|
803
|
-
### Callback URL Mismatch
|
|
804
|
-
|
|
805
|
-
- Ensure the callback URL in Auth0 dashboard matches your \`redirectUri\`
|
|
806
|
-
- For production, update the callback URL to your production domain
|
|
807
|
-
|
|
808
|
-
### CORS Errors
|
|
809
|
-
|
|
810
|
-
- Add your domain to "Allowed Web Origins" in Auth0 dashboard
|
|
811
|
-
- Ensure "Allowed Origins (CORS)" includes your domain
|
|
812
|
-
|
|
813
|
-
## API Reference
|
|
814
|
-
|
|
815
|
-
### AuthService Methods
|
|
816
|
-
|
|
817
|
-
#### \`loginWithAuth0Redirect()\`
|
|
818
|
-
Redirects user to Auth0 login page. User will leave your application.
|
|
819
|
-
|
|
820
|
-
**Returns**: Promise<void>
|
|
821
|
-
|
|
822
|
-
#### \`loginWithAuth0Popup()\`
|
|
823
|
-
Opens Auth0 login in a popup window. User stays on your application.
|
|
824
|
-
|
|
825
|
-
**Returns**: Promise<User>
|
|
826
|
-
|
|
827
|
-
#### \`handleAuth0Callback()\`
|
|
828
|
-
Handles the OAuth callback after redirect. Call this on your callback page.
|
|
829
|
-
|
|
830
|
-
**Returns**: Promise<User>
|
|
831
|
-
|
|
832
|
-
#### \`linkAuth0Account()\`
|
|
833
|
-
Links Auth0 account to currently logged-in Meteor user.
|
|
834
|
-
|
|
835
|
-
**Returns**: Promise<boolean>
|
|
836
|
-
|
|
837
|
-
**Throws**: Error if user not logged in or account already linked
|
|
838
|
-
|
|
839
|
-
#### \`unlinkAuth0Account()\`
|
|
840
|
-
Removes Auth0 link from current user.
|
|
841
|
-
|
|
842
|
-
**Returns**: Promise<boolean>
|
|
843
|
-
|
|
844
|
-
**Throws**: Error if Auth0 is the only login method
|
|
845
|
-
|
|
846
|
-
#### \`logoutAuth0()\`
|
|
847
|
-
Logs out from both Meteor and Auth0.
|
|
848
|
-
|
|
849
|
-
**Returns**: Promise<void>
|
|
850
|
-
|
|
851
|
-
## Next Steps
|
|
852
|
-
|
|
853
|
-
1. **Generate UI Components**: Run \`maka g:k:m:auth0\` to generate MUI login components
|
|
854
|
-
2. **Customize User Profile**: Add additional user fields from Auth0 token
|
|
855
|
-
3. **Add Roles**: Integrate with \`alanning:roles\` for authorization
|
|
856
|
-
4. **Production Setup**: Update callback URLs for production domain
|
|
857
|
-
5. **Social Connections**: Enable social login providers in Auth0 dashboard
|
|
858
|
-
|
|
859
|
-
## Additional Resources
|
|
860
|
-
|
|
861
|
-
- [Auth0 Documentation](https://auth0.com/docs)
|
|
862
|
-
- [Auth0 SPA SDK](https://auth0.com/docs/libraries/auth0-spa-js)
|
|
863
|
-
- [Meteor Accounts](https://docs.meteor.com/api/accounts.html)
|
|
864
|
-
- [JWT.io](https://jwt.io/) - Debug JWT tokens
|
|
865
|
-
|
|
866
|
-
## Support
|
|
867
|
-
|
|
868
|
-
For issues specific to this integration, please check:
|
|
869
|
-
- Auth0 dashboard for application configuration
|
|
870
|
-
- Browser console for client-side errors
|
|
871
|
-
- Meteor server logs for server-side errors
|
|
872
|
-
- Network tab to inspect Auth0 API calls
|
|
562
|
+
const readmeContent = `# Auth0 Authentication Integration
|
|
563
|
+
|
|
564
|
+
This document explains how Auth0 authentication has been integrated into your Meteor application.
|
|
565
|
+
|
|
566
|
+
## Overview
|
|
567
|
+
|
|
568
|
+
This integration provides a complete Auth0 authentication solution that:
|
|
569
|
+
|
|
570
|
+
- ✅ Supports both redirect and popup login flows
|
|
571
|
+
- ✅ Validates JWT tokens server-side using JWKS
|
|
572
|
+
- ✅ Automatically creates or links Meteor user accounts
|
|
573
|
+
- ✅ Allows account linking for existing users
|
|
574
|
+
- ✅ Provides seamless integration with your existing AuthContext
|
|
575
|
+
|
|
576
|
+
## Architecture
|
|
577
|
+
|
|
578
|
+
### Client-Side Components
|
|
579
|
+
|
|
580
|
+
**\`${resourceTopLevelPathLib}/auth0-config.${jsEngine}\`**
|
|
581
|
+
- Centralized Auth0 configuration
|
|
582
|
+
- Reads settings from \`Meteor.settings.public.auth0\`
|
|
583
|
+
- Provides configuration for both client and server
|
|
584
|
+
|
|
585
|
+
**\`${resourceTopLevelPathClient}/auth0-client.${jsEngine}\`**
|
|
586
|
+
- Auth0 SDK wrapper functions
|
|
587
|
+
- Handles login redirects and popups
|
|
588
|
+
- Manages Auth0 client instance
|
|
589
|
+
- Retrieves ID tokens
|
|
590
|
+
|
|
591
|
+
**\`${resourceTopLevelPathClient}/authentication-service.${jsEngine}\`**
|
|
592
|
+
- Extended with Auth0 authentication methods
|
|
593
|
+
- Bridges Auth0 with Meteor accounts
|
|
594
|
+
- Provides static methods for all Auth0 operations
|
|
595
|
+
|
|
596
|
+
**\`${resourceTopLevelPathClient}/authentication-provider.${jsEngine}\`**
|
|
597
|
+
- Context updated with Auth0 methods
|
|
598
|
+
- Makes Auth0 functions available throughout your app
|
|
599
|
+
|
|
600
|
+
### Server-Side Components
|
|
601
|
+
|
|
602
|
+
**\`${resourceTopLevelPathServer}/auth0-validator.${jsEngine}\`**
|
|
603
|
+
- JWT token validation using JWKS
|
|
604
|
+
- Verifies token signature and claims
|
|
605
|
+
- Creates/updates user accounts from Auth0 data
|
|
606
|
+
|
|
607
|
+
**\`${resourceTopLevelPathServer}/methods/auth0-methods.${jsEngine}\`**
|
|
608
|
+
- Meteor methods for Auth0 operations
|
|
609
|
+
- \`auth0.login\` - Authenticates with ID token
|
|
610
|
+
- \`auth0.linkAccount\` - Links Auth0 to existing user
|
|
611
|
+
- \`auth0.unlinkAccount\` - Removes Auth0 link
|
|
612
|
+
|
|
613
|
+
## Setup Instructions
|
|
614
|
+
|
|
615
|
+
### 1. Configure Auth0 Application
|
|
616
|
+
|
|
617
|
+
1. Go to [Auth0 Dashboard](https://manage.auth0.com/)
|
|
618
|
+
2. Create a new application (Single Page Application)
|
|
619
|
+
3. Configure the following settings:
|
|
620
|
+
- **Allowed Callback URLs**: \`http://localhost:3000/auth/callback\`
|
|
621
|
+
- **Allowed Logout URLs**: \`http://localhost:3000\`
|
|
622
|
+
- **Allowed Web Origins**: \`http://localhost:3000\`
|
|
623
|
+
- **Allowed Origins (CORS)**: \`http://localhost:3000\`
|
|
624
|
+
|
|
625
|
+
### 2. Update Configuration
|
|
626
|
+
|
|
627
|
+
Edit \`settings.auth0.json\` with your Auth0 credentials:
|
|
628
|
+
|
|
629
|
+
\`\`\`json
|
|
630
|
+
{
|
|
631
|
+
"public": {
|
|
632
|
+
"auth0": {
|
|
633
|
+
"domain": "your-domain.auth0.com",
|
|
634
|
+
"clientId": "your_client_id",
|
|
635
|
+
"audience": "https://your-domain.auth0.com/api/v2/",
|
|
636
|
+
"redirectUri": "http://localhost:3000/auth/callback",
|
|
637
|
+
"scope": "openid profile email"
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
"auth0": {
|
|
641
|
+
"domain": "your-domain.auth0.com",
|
|
642
|
+
"clientId": "your_client_id",
|
|
643
|
+
"clientSecret": "your_client_secret",
|
|
644
|
+
"audience": "https://your-domain.auth0.com/api/v2/",
|
|
645
|
+
"redirectUri": "http://localhost:3000/auth/callback",
|
|
646
|
+
"scope": "openid profile email"
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
\`\`\`
|
|
650
|
+
|
|
651
|
+
### 3. Start Your Application
|
|
652
|
+
|
|
653
|
+
\`\`\`bash
|
|
654
|
+
cd app
|
|
655
|
+
meteor --settings ../settings.auth0.json
|
|
656
|
+
\`\`\`
|
|
657
|
+
|
|
658
|
+
## Usage
|
|
659
|
+
|
|
660
|
+
### Using Auth0 in Components
|
|
661
|
+
|
|
662
|
+
The Auth0 methods are available through the AuthContext:
|
|
663
|
+
|
|
664
|
+
\`\`\`${jsEngine === 'tsx' ? 'typescript' : 'javascript'}
|
|
665
|
+
import React, { useContext } from 'react';
|
|
666
|
+
import { AuthContext } from '${resourceTopLevelPathClient}/authentication-provider';
|
|
667
|
+
|
|
668
|
+
function LoginButton() {
|
|
669
|
+
const auth = useContext(AuthContext);
|
|
670
|
+
|
|
671
|
+
const handleLogin = async () => {
|
|
672
|
+
try {
|
|
673
|
+
// Option 1: Redirect flow (recommended)
|
|
674
|
+
await auth.loginWithAuth0Redirect?.();
|
|
675
|
+
|
|
676
|
+
// Option 2: Popup flow
|
|
677
|
+
// const user = await auth.loginWithAuth0Popup?.();
|
|
678
|
+
// console.log('Logged in user:', user);
|
|
679
|
+
} catch (error) {
|
|
680
|
+
console.error('Login failed:', error);
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
return <button onClick={handleLogin}>Login with Auth0</button>;
|
|
685
|
+
}
|
|
686
|
+
\`\`\`
|
|
687
|
+
|
|
688
|
+
### Using AuthService Directly
|
|
689
|
+
|
|
690
|
+
You can also use the AuthService static methods:
|
|
691
|
+
|
|
692
|
+
\`\`\`${jsEngine === 'tsx' ? 'typescript' : 'javascript'}
|
|
693
|
+
import AuthService from '${resourceTopLevelPathClient}/authentication-service';
|
|
694
|
+
|
|
695
|
+
// Redirect login
|
|
696
|
+
await AuthService.loginWithAuth0Redirect();
|
|
697
|
+
|
|
698
|
+
// Popup login
|
|
699
|
+
const user = await AuthService.loginWithAuth0Popup();
|
|
700
|
+
|
|
701
|
+
// Handle callback (use in callback page)
|
|
702
|
+
const user = await AuthService.handleAuth0Callback();
|
|
703
|
+
|
|
704
|
+
// Link Auth0 to logged-in user
|
|
705
|
+
await AuthService.linkAuth0Account();
|
|
706
|
+
|
|
707
|
+
// Unlink Auth0 account
|
|
708
|
+
await AuthService.unlinkAuth0Account();
|
|
709
|
+
|
|
710
|
+
// Logout from both Auth0 and Meteor
|
|
711
|
+
await AuthService.logoutAuth0();
|
|
712
|
+
\`\`\`
|
|
713
|
+
|
|
714
|
+
## Authentication Flow
|
|
715
|
+
|
|
716
|
+
### Redirect Flow
|
|
717
|
+
|
|
718
|
+
1. User clicks login button
|
|
719
|
+
2. \`loginWithAuth0Redirect()\` redirects to Auth0 login page
|
|
720
|
+
3. User authenticates with Auth0
|
|
721
|
+
4. Auth0 redirects back to \`/auth/callback\`
|
|
722
|
+
5. Callback page calls \`handleAuth0Callback()\`
|
|
723
|
+
6. Server validates JWT and creates/links Meteor user
|
|
724
|
+
7. User is logged into Meteor and redirected to home page
|
|
725
|
+
|
|
726
|
+
### Popup Flow
|
|
727
|
+
|
|
728
|
+
1. User clicks login button
|
|
729
|
+
2. \`loginWithAuth0Popup()\` opens Auth0 login in popup
|
|
730
|
+
3. User authenticates with Auth0
|
|
731
|
+
4. Popup closes and ID token is returned
|
|
732
|
+
5. Server validates JWT and creates/links Meteor user
|
|
733
|
+
6. User is logged into Meteor
|
|
734
|
+
7. Component receives user object
|
|
735
|
+
|
|
736
|
+
## Account Linking
|
|
737
|
+
|
|
738
|
+
Users can link their Auth0 account to an existing Meteor account:
|
|
739
|
+
|
|
740
|
+
\`\`\`${jsEngine === 'tsx' ? 'typescript' : 'javascript'}
|
|
741
|
+
// User must be logged in first
|
|
742
|
+
const auth = useContext(AuthContext);
|
|
743
|
+
await auth.linkAuth0Account?.();
|
|
744
|
+
\`\`\`
|
|
745
|
+
|
|
746
|
+
This allows users to:
|
|
747
|
+
- Login with either Meteor credentials or Auth0
|
|
748
|
+
- Maintain a single user account with multiple login methods
|
|
749
|
+
- Unlink Auth0 if they no longer want to use it
|
|
750
|
+
|
|
751
|
+
## User Data Structure
|
|
752
|
+
|
|
753
|
+
When a user logs in with Auth0, their Meteor user document includes:
|
|
754
|
+
|
|
755
|
+
\`\`\`javascript
|
|
756
|
+
{
|
|
757
|
+
_id: "userId",
|
|
758
|
+
emails: [{ address: "user@example.com", verified: true }],
|
|
759
|
+
profile: { name: "John Doe" },
|
|
760
|
+
services: {
|
|
761
|
+
auth0: {
|
|
762
|
+
id: "auth0|123456789",
|
|
763
|
+
email: "user@example.com",
|
|
764
|
+
name: "John Doe",
|
|
765
|
+
picture: "https://...",
|
|
766
|
+
email_verified: true
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
\`\`\`
|
|
771
|
+
|
|
772
|
+
## Security Features
|
|
773
|
+
|
|
774
|
+
- **JWT Validation**: Tokens are verified using Auth0's JWKS endpoint
|
|
775
|
+
- **Token Expiration**: Tokens are checked for expiration
|
|
776
|
+
- **Issuer Verification**: Ensures tokens come from your Auth0 domain
|
|
777
|
+
- **Audience Verification**: Validates tokens are for your application
|
|
778
|
+
- **Account Linking Protection**: Prevents duplicate account linking
|
|
779
|
+
|
|
780
|
+
## Troubleshooting
|
|
781
|
+
|
|
782
|
+
### "Login failed: Invalid token" Error After Successful Login
|
|
783
|
+
|
|
784
|
+
If you see this error message even though you're logged in, it's because the placeholder token validation code is still running. The Auth0 kit automatically comments out this code, but if you see this error:
|
|
785
|
+
|
|
786
|
+
1. Check your \`authentication-provider.${jsEngine}\` file
|
|
787
|
+
2. Look for the \`loginUserWithToken\` call in the \`useEffect\` hook
|
|
788
|
+
3. Ensure it's commented out (the generator does this automatically)
|
|
789
|
+
4. Meteor's authentication system handles token validation automatically
|
|
790
|
+
|
|
791
|
+
### "Invalid token" Error During Login
|
|
792
|
+
|
|
793
|
+
- Check that your Auth0 domain and clientId are correct
|
|
794
|
+
- Verify the token hasn't expired
|
|
795
|
+
- Ensure your Auth0 application settings are configured correctly
|
|
796
|
+
- Make sure the domain in settings.json doesn't include \`https://\` (the kit handles this automatically)
|
|
797
|
+
|
|
798
|
+
### "Auth0 configuration missing" Error
|
|
799
|
+
|
|
800
|
+
- Make sure you're starting Meteor with \`--settings ../settings.auth0.json\`
|
|
801
|
+
- Verify the settings file contains all required Auth0 configuration
|
|
802
|
+
|
|
803
|
+
### Callback URL Mismatch
|
|
804
|
+
|
|
805
|
+
- Ensure the callback URL in Auth0 dashboard matches your \`redirectUri\`
|
|
806
|
+
- For production, update the callback URL to your production domain
|
|
807
|
+
|
|
808
|
+
### CORS Errors
|
|
809
|
+
|
|
810
|
+
- Add your domain to "Allowed Web Origins" in Auth0 dashboard
|
|
811
|
+
- Ensure "Allowed Origins (CORS)" includes your domain
|
|
812
|
+
|
|
813
|
+
## API Reference
|
|
814
|
+
|
|
815
|
+
### AuthService Methods
|
|
816
|
+
|
|
817
|
+
#### \`loginWithAuth0Redirect()\`
|
|
818
|
+
Redirects user to Auth0 login page. User will leave your application.
|
|
819
|
+
|
|
820
|
+
**Returns**: Promise<void>
|
|
821
|
+
|
|
822
|
+
#### \`loginWithAuth0Popup()\`
|
|
823
|
+
Opens Auth0 login in a popup window. User stays on your application.
|
|
824
|
+
|
|
825
|
+
**Returns**: Promise<User>
|
|
826
|
+
|
|
827
|
+
#### \`handleAuth0Callback()\`
|
|
828
|
+
Handles the OAuth callback after redirect. Call this on your callback page.
|
|
829
|
+
|
|
830
|
+
**Returns**: Promise<User>
|
|
831
|
+
|
|
832
|
+
#### \`linkAuth0Account()\`
|
|
833
|
+
Links Auth0 account to currently logged-in Meteor user.
|
|
834
|
+
|
|
835
|
+
**Returns**: Promise<boolean>
|
|
836
|
+
|
|
837
|
+
**Throws**: Error if user not logged in or account already linked
|
|
838
|
+
|
|
839
|
+
#### \`unlinkAuth0Account()\`
|
|
840
|
+
Removes Auth0 link from current user.
|
|
841
|
+
|
|
842
|
+
**Returns**: Promise<boolean>
|
|
843
|
+
|
|
844
|
+
**Throws**: Error if Auth0 is the only login method
|
|
845
|
+
|
|
846
|
+
#### \`logoutAuth0()\`
|
|
847
|
+
Logs out from both Meteor and Auth0.
|
|
848
|
+
|
|
849
|
+
**Returns**: Promise<void>
|
|
850
|
+
|
|
851
|
+
## Next Steps
|
|
852
|
+
|
|
853
|
+
1. **Generate UI Components**: Run \`maka g:k:m:auth0\` to generate MUI login components
|
|
854
|
+
2. **Customize User Profile**: Add additional user fields from Auth0 token
|
|
855
|
+
3. **Add Roles**: Integrate with \`alanning:roles\` for authorization
|
|
856
|
+
4. **Production Setup**: Update callback URLs for production domain
|
|
857
|
+
5. **Social Connections**: Enable social login providers in Auth0 dashboard
|
|
858
|
+
|
|
859
|
+
## Additional Resources
|
|
860
|
+
|
|
861
|
+
- [Auth0 Documentation](https://auth0.com/docs)
|
|
862
|
+
- [Auth0 SPA SDK](https://auth0.com/docs/libraries/auth0-spa-js)
|
|
863
|
+
- [Meteor Accounts](https://docs.meteor.com/api/accounts.html)
|
|
864
|
+
- [JWT.io](https://jwt.io/) - Debug JWT tokens
|
|
865
|
+
|
|
866
|
+
## Support
|
|
867
|
+
|
|
868
|
+
For issues specific to this integration, please check:
|
|
869
|
+
- Auth0 dashboard for application configuration
|
|
870
|
+
- Browser console for client-side errors
|
|
871
|
+
- Meteor server logs for server-side errors
|
|
872
|
+
- Network tab to inspect Auth0 API calls
|
|
873
873
|
`;
|
|
874
874
|
if (!fsi.isFile(readmePath) || shouldForce) {
|
|
875
875
|
fsi.writeToFile({
|