refactor: session and user
This commit is contained in:
parent
00f1654ed9
commit
61f1a5b1f2
|
@ -9,11 +9,15 @@
|
|||
'@flecks/electron': {}
|
||||
'@flecks/fleck': {}
|
||||
'@flecks/governor': {}
|
||||
'@flecks/passport-local-react': {}
|
||||
'@flecks/passport-local': {}
|
||||
'@flecks/passport-react': {}
|
||||
'@flecks/passport': {}
|
||||
'@flecks/react': {}
|
||||
'@flecks/redis': {}
|
||||
'@flecks/redux': {}
|
||||
'@flecks/repl': {}
|
||||
'@flecks/server': {}
|
||||
'@flecks/session': {}
|
||||
'@flecks/socket': {}
|
||||
'@flecks/user': {}
|
||||
'@flecks/web': {}
|
||||
|
|
|
@ -25,8 +25,12 @@
|
|||
"@flecks/redux": "*",
|
||||
"@flecks/repl": "*",
|
||||
"@flecks/server": "*",
|
||||
"@flecks/session": "*",
|
||||
"@flecks/socket": "*",
|
||||
"@flecks/user": "*",
|
||||
"@flecks/passport": "*",
|
||||
"@flecks/passport-local": "*",
|
||||
"@flecks/passport-local-react": "*",
|
||||
"@flecks/passport-react": "*",
|
||||
"@flecks/web": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -114,3 +114,6 @@ dist
|
|||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# copy-webpack-plugin charity
|
||||
.git
|
3
packages/passport-local-react/build/flecks.config.js
Normal file
3
packages/passport-local-react/build/flecks.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
dependencies: ['@flecks/passport-local', '@flecks/passport-react'],
|
||||
};
|
|
@ -1,3 +1,3 @@
|
|||
'@flecks/core': {}
|
||||
'@flecks/react': {}
|
||||
'@flecks/fleck': {}
|
||||
'@flecks/react': {}
|
30
packages/passport-local-react/package.json
Normal file
30
packages/passport-local-react/package.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "@flecks/passport-local-react",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cha0s/flecks.git",
|
||||
"directory": "packages/passport-local-react"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "2.0.3",
|
||||
"scripts": {
|
||||
"build": "flecks build",
|
||||
"clean": "flecks clean",
|
||||
"lint": "flecks lint",
|
||||
"postversion": "cp package.json dist",
|
||||
"test": "flecks test"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@flecks/core": "^2.0.0",
|
||||
"@flecks/passport-local": "^2.0.0",
|
||||
"@flecks/react": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@flecks/fleck": "^2.0.0"
|
||||
}
|
||||
}
|
9
packages/passport-local-react/src/index.js
Normal file
9
packages/passport-local-react/src/index.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import {React} from '@flecks/react';
|
||||
|
||||
import PassportLocalLogin from './login';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/passport-react.strategies': () => ({
|
||||
Email: React.createElement(PassportLocalLogin),
|
||||
}),
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable jsx-a11y/control-has-associated-label */
|
||||
import {React} from '@flecks/react';
|
||||
|
||||
function UserLocalLogin() {
|
||||
function PassportLocalLogin() {
|
||||
return (
|
||||
<form action="/auth/local" method="post">
|
||||
<label>
|
||||
|
@ -17,13 +17,11 @@ function UserLocalLogin() {
|
|||
<input type="checkbox" />
|
||||
<span>Remember me</span>
|
||||
</label>
|
||||
<a href="/auth/forgot">Forgot password?</a>
|
||||
<a href="/auth/local/forgot">Forgot password?</a>
|
||||
</div>
|
||||
<label>
|
||||
<input type="submit" value="Sign in" />
|
||||
</label>
|
||||
<input type="submit" value="Sign in" />
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default UserLocalLogin;
|
||||
export default PassportLocalLogin;
|
119
packages/passport-local/.gitignore
vendored
Normal file
119
packages/passport-local/.gitignore
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# copy-webpack-plugin charity
|
||||
.git
|
3
packages/passport-local/build/flecks.config.js
Normal file
3
packages/passport-local/build/flecks.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
dependencies: ['@flecks/passport'],
|
||||
};
|
31
packages/passport-local/package.json
Normal file
31
packages/passport-local/package.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "@flecks/passport-local",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cha0s/flecks.git",
|
||||
"directory": "packages/passport-local"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "2.0.3",
|
||||
"scripts": {
|
||||
"build": "flecks build",
|
||||
"clean": "flecks clean",
|
||||
"lint": "flecks lint",
|
||||
"postversion": "cp package.json dist",
|
||||
"test": "flecks test"
|
||||
},
|
||||
"files": [
|
||||
"server.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@flecks/core": "^2.0.3",
|
||||
"@flecks/passport": "^2.0.3",
|
||||
"bcrypt": "^5.1.1",
|
||||
"passport-local": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@flecks/fleck": "^2.0.3"
|
||||
}
|
||||
}
|
45
packages/passport-local/src/server/index.js
Normal file
45
packages/passport-local/src/server/index.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
import {randomBytes} from 'crypto';
|
||||
|
||||
import {Flecks} from '@flecks/core';
|
||||
import LocalStrategy from 'passport-local';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/db/server.models.decorate': Flecks.decorate(require.context('./models/decorators')),
|
||||
'@flecks/passport.strategies': (passport, flecks) => ({
|
||||
local: new LocalStrategy(
|
||||
{usernameField: 'email'},
|
||||
async (email, password, fn) => {
|
||||
const {User} = flecks.db.Models;
|
||||
try {
|
||||
const user = await User.findOne({where: {email}});
|
||||
fn(undefined, user && await user.validatePassword(password) && user);
|
||||
}
|
||||
catch (error) {
|
||||
fn(error);
|
||||
}
|
||||
},
|
||||
),
|
||||
}),
|
||||
'@flecks/repl.commands': (flecks) => {
|
||||
const {User} = flecks.db.Models;
|
||||
return {
|
||||
createUser: async (spec) => {
|
||||
const [email, maybePassword] = spec.split(' ', 2);
|
||||
const password = maybePassword || randomBytes(8).toString('hex');
|
||||
const user = User.build({email});
|
||||
await user.addHashedPassword(password);
|
||||
await user.save();
|
||||
},
|
||||
resetPassword: async (email) => {
|
||||
const password = randomBytes(8).toString('hex');
|
||||
const user = await User.findOne({where: {email}});
|
||||
if (user) {
|
||||
await user.addHashedPassword(password);
|
||||
await user.save();
|
||||
return `\nNew password: ${password}\n\n`;
|
||||
}
|
||||
return 'User not found.\n';
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
119
packages/passport-react/.gitignore
vendored
Normal file
119
packages/passport-react/.gitignore
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# copy-webpack-plugin charity
|
||||
.git
|
3
packages/passport-react/build/flecks.config.js
Normal file
3
packages/passport-react/build/flecks.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
dependencies: ['@flecks/passport', '@flecks/react'],
|
||||
};
|
3
packages/passport-react/build/flecks.yml
Normal file
3
packages/passport-react/build/flecks.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
'@flecks/core': {}
|
||||
'@flecks/fleck': {}
|
||||
'@flecks/react': {}
|
31
packages/passport-react/package.json
Normal file
31
packages/passport-react/package.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "@flecks/passport-react",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cha0s/flecks.git",
|
||||
"directory": "packages/passport-react"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "2.0.3",
|
||||
"scripts": {
|
||||
"build": "flecks build",
|
||||
"clean": "flecks clean",
|
||||
"lint": "flecks lint",
|
||||
"postversion": "cp package.json dist",
|
||||
"test": "flecks test"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@flecks/core": "^2.0.0",
|
||||
"@flecks/passport": "^2.0.0",
|
||||
"@flecks/react": "^2.0.0",
|
||||
"@flecks/redux": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@flecks/fleck": "^2.0.0"
|
||||
}
|
||||
}
|
2
packages/passport-react/src/index.js
Normal file
2
packages/passport-react/src/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
export {default as Login} from './login';
|
||||
export {default as UserRequired} from './user-required';
|
24
packages/passport-react/src/login.jsx
Normal file
24
packages/passport-react/src/login.jsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import {React, useFlecks} from '@flecks/react';
|
||||
import {
|
||||
Tab,
|
||||
Tabs,
|
||||
TabList,
|
||||
TabPanel,
|
||||
} from '@flecks/react/tabs';
|
||||
|
||||
function Login() {
|
||||
const flecks = useFlecks();
|
||||
const strategies = Object.entries(flecks.invokeMergeUnique('@flecks/passport-react.strategies'));
|
||||
return (
|
||||
<Tabs>
|
||||
<TabList>
|
||||
{strategies.map(([tab]) => <Tab key={tab}>{tab}</Tab>)}
|
||||
</TabList>
|
||||
<div className="behaved__tab-panels">
|
||||
{strategies.map(([tab, panel]) => <TabPanel key={tab}>{panel}</TabPanel>)}
|
||||
</div>
|
||||
</Tabs>
|
||||
);
|
||||
}
|
||||
|
||||
export default Login;
|
|
@ -1,7 +1,7 @@
|
|||
import {PropTypes, React} from '@flecks/react';
|
||||
import {Navigate, useLocation} from '@flecks/react/router';
|
||||
import {useSelector} from '@flecks/redux';
|
||||
import {userIdSelector} from '@flecks/user/state';
|
||||
import {userIdSelector} from '@flecks/passport';
|
||||
|
||||
function UserRequired({children, destination}) {
|
||||
const location = useLocation();
|
119
packages/passport/.gitignore
vendored
Normal file
119
packages/passport/.gitignore
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# copy-webpack-plugin charity
|
||||
.git
|
3
packages/passport/build/flecks.config.js
Normal file
3
packages/passport/build/flecks.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
dependencies: ['@flecks/db', '@flecks/session'],
|
||||
};
|
|
@ -1,15 +1,14 @@
|
|||
{
|
||||
"name": "@flecks/user",
|
||||
"name": "@flecks/passport",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cha0s/flecks.git",
|
||||
"directory": "packages/user"
|
||||
"directory": "packages/passport"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "2.0.3",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "flecks build",
|
||||
"clean": "flecks clean",
|
||||
|
@ -18,25 +17,17 @@
|
|||
"test": "flecks test"
|
||||
},
|
||||
"files": [
|
||||
"client.js",
|
||||
"index.js",
|
||||
"local.js",
|
||||
"local/server.js",
|
||||
"server.js",
|
||||
"session/server.js"
|
||||
"server.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@flecks/core": "^2.0.3",
|
||||
"@flecks/react": "^2.0.3",
|
||||
"@flecks/db": "^2.0.3",
|
||||
"@flecks/redux": "^2.0.3",
|
||||
"bcrypt": "^5.0.0",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "1.17.1",
|
||||
"passport": "0.4.1",
|
||||
"passport-local": "^1.0.0"
|
||||
"@flecks/session": "^2.0.3",
|
||||
"passport": "^0.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-react": "^7.12.10",
|
||||
"@flecks/fleck": "^2.0.3"
|
||||
}
|
||||
}
|
10
packages/passport/src/index.js
Normal file
10
packages/passport/src/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import {Flecks} from '@flecks/core';
|
||||
|
||||
import {user, users} from './state';
|
||||
|
||||
export * from './state';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/redux.slices': () => ({user, users}),
|
||||
'@flecks/socket.packets': Flecks.provide(require.context('./packets')),
|
||||
};
|
4
packages/passport/src/packets/logout.js
Normal file
4
packages/passport/src/packets/logout.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
export default (flecks) => {
|
||||
const {Packet} = flecks.fleck('@flecks/socket');
|
||||
return class Logout extends Packet {};
|
||||
};
|
143
packages/passport/src/server/index.js
Normal file
143
packages/passport/src/server/index.js
Normal file
|
@ -0,0 +1,143 @@
|
|||
import {D, Flecks} from '@flecks/core';
|
||||
import passport from 'passport';
|
||||
import LogOps from 'passport/lib/http/request';
|
||||
|
||||
const debug = D('@flecks/passport');
|
||||
const debugSilly = debug.extend('silly');
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/core.config': () => ({
|
||||
/**
|
||||
* Path to redirect to after failed login.
|
||||
*/
|
||||
failureRedirect: '/',
|
||||
/**
|
||||
* Path to redirect to after logout.
|
||||
*/
|
||||
logoutRedirect: '/',
|
||||
/**
|
||||
* Path to redirect to after successful login.
|
||||
*/
|
||||
successRedirect: '/',
|
||||
}),
|
||||
'@flecks/core.mixin': (Flecks) => (
|
||||
class FlecksWithSession extends Flecks {
|
||||
|
||||
passport;
|
||||
|
||||
}
|
||||
),
|
||||
'@flecks/db/server.models': Flecks.provide(require.context('./models')),
|
||||
'@flecks/socket.packets.decorate': Flecks.decorate(require.context('./packets/decorators')),
|
||||
'@flecks/web/server.request.route': Flecks.priority(
|
||||
(flecks) => (req, res, next) => {
|
||||
flecks.passport.initialize(req, res, () => {
|
||||
debugSilly('@flecks/web/server.request.route: passport.session()');
|
||||
flecks.passport.session(req, res, () => {
|
||||
if (!req.user) {
|
||||
const {User} = flecks.db.Models;
|
||||
req.user = new User();
|
||||
req.user.id = 0;
|
||||
}
|
||||
else {
|
||||
debugSilly('web user ID: %s', req.user.id);
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
{after: '@flecks/session/server'},
|
||||
),
|
||||
'@flecks/server.up': Flecks.priority(
|
||||
async (flecks) => {
|
||||
passport.serializeUser((user, fn) => fn(null, user.id));
|
||||
passport.deserializeUser(async (id, fn) => {
|
||||
const {User} = flecks.db.Models;
|
||||
try {
|
||||
fn(undefined, await User.findByPk(id));
|
||||
}
|
||||
catch (error) {
|
||||
fn(error);
|
||||
}
|
||||
});
|
||||
flecks.passport = {
|
||||
initialize: passport.initialize(),
|
||||
session: passport.session(),
|
||||
strategies: flecks.invokeMergeUnique('@flecks/passport.strategies', passport),
|
||||
};
|
||||
Object.entries(flecks.passport.strategies)
|
||||
.forEach(([name, strategy]) => {
|
||||
passport.use(name, strategy);
|
||||
});
|
||||
},
|
||||
{before: '@flecks/web/server', after: ['@flecks/db/server', '@flecks/session/server']},
|
||||
),
|
||||
'@flecks/socket.intercom': () => ({
|
||||
'@flecks/passport.users': async (sids, server) => {
|
||||
const sockets = await server.sockets();
|
||||
return sids
|
||||
.filter((sid) => sockets.has(sid))
|
||||
.reduce(
|
||||
(r, sid) => ({
|
||||
...r,
|
||||
[sid]: sockets.get(sid).handshake.user.id,
|
||||
}),
|
||||
{},
|
||||
);
|
||||
},
|
||||
}),
|
||||
'@flecks/socket/server.request.socket': Flecks.priority(
|
||||
(flecks) => (socket, next) => {
|
||||
const {req} = socket;
|
||||
flecks.passport.initialize(req, undefined, () => {
|
||||
flecks.passport.session(req, undefined, async () => {
|
||||
if (!req.user) {
|
||||
const {User} = flecks.db.Models;
|
||||
req.user = new User();
|
||||
req.user.id = 0;
|
||||
}
|
||||
else {
|
||||
debugSilly('socket user ID: %s', req.user.id);
|
||||
}
|
||||
req.login = LogOps.logIn;
|
||||
req.logIn = LogOps.logIn;
|
||||
req.logout = LogOps.logOut;
|
||||
req.logOut = LogOps.logOut;
|
||||
req.isAuthenticated = LogOps.isAuthenticated;
|
||||
req.isUnauthenticated = LogOps.isUnauthenticated;
|
||||
await socket.join(`/u/${req.user.id}`);
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
{after: '@flecks/session/server', before: '@flecks/governor/server'},
|
||||
),
|
||||
'@flecks/web.routes': (flecks) => {
|
||||
const {
|
||||
failureRedirect,
|
||||
logoutRedirect,
|
||||
successRedirect,
|
||||
} = flecks.get('@flecks/passport/server');
|
||||
const routes = [
|
||||
{
|
||||
method: 'get',
|
||||
path: '/auth/logout',
|
||||
middleware: (req, res) => {
|
||||
req.logout();
|
||||
res.redirect(logoutRedirect);
|
||||
},
|
||||
},
|
||||
];
|
||||
Object.entries(flecks.passport.strategies)
|
||||
.forEach(([name]) => {
|
||||
routes.push(
|
||||
{
|
||||
method: 'post',
|
||||
path: `/auth/${name}`,
|
||||
middleware: passport.authenticate(name, {failureRedirect, successRedirect}),
|
||||
},
|
||||
);
|
||||
});
|
||||
return routes;
|
||||
},
|
||||
};
|
21
packages/passport/src/server/packets/decorators/logout.js
Normal file
21
packages/passport/src/server/packets/decorators/logout.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
export default (Logout, flecks) => {
|
||||
const {ValidationError} = flecks.fleck('@flecks/socket');
|
||||
return class ServerLogout extends Logout {
|
||||
|
||||
static async respond(packet, socket) {
|
||||
const {req} = socket;
|
||||
req.logout();
|
||||
await new Promise((r, e) => {
|
||||
req.session.save((error) => (error ? e(error) : r()));
|
||||
});
|
||||
socket.send(['Redirect', flecks.get('@flecks/passport/server.logoutRedirect')]);
|
||||
}
|
||||
|
||||
static validate(packet, {req}) {
|
||||
if (!req.user) {
|
||||
throw new ValidationError({code: 400, reason: 'anonymous'});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
|
@ -14,7 +14,7 @@ export const userSelector = createSelector(
|
|||
);
|
||||
|
||||
const slice = createSlice({
|
||||
name: '@flecks/user.user',
|
||||
name: '@flecks/passport.user',
|
||||
initialState: 0,
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(hydrateServer, (state, action) => {
|
|
@ -15,7 +15,7 @@ export const {
|
|||
} = adapter.getSelectors((state) => state.users);
|
||||
|
||||
const slice = createSlice({
|
||||
name: '@flecks/user.users',
|
||||
name: '@flecks/passport.users',
|
||||
initialState: adapter.getInitialState({
|
||||
entities: {0: {name: 'anonymous'}},
|
||||
ids: [0],
|
|
@ -13,10 +13,10 @@ const RedisStore = ConnectRedis(session);
|
|||
export const hooks = {
|
||||
'@flecks/core.priority': (graph, hook) => {
|
||||
if ('@flecks/server.up' === hook) {
|
||||
graph.addDependency('@flecks/user/session/server', '@flecks/redis/server');
|
||||
graph.addDependency('@flecks/session/server', '@flecks/redis/server');
|
||||
}
|
||||
},
|
||||
'@flecks/user.session': async (flecks) => {
|
||||
'@flecks/session.config': async (flecks) => {
|
||||
const client = createClient(flecks, {legacyMode: true});
|
||||
await client.connect();
|
||||
return {
|
||||
|
|
119
packages/session/.gitignore
vendored
Normal file
119
packages/session/.gitignore
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# copy-webpack-plugin charity
|
||||
.git
|
30
packages/session/package.json
Normal file
30
packages/session/package.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "@flecks/session",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cha0s/flecks.git",
|
||||
"directory": "packages/session"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"version": "2.0.3",
|
||||
"scripts": {
|
||||
"build": "flecks build",
|
||||
"clean": "flecks clean",
|
||||
"lint": "flecks lint",
|
||||
"postversion": "cp package.json dist",
|
||||
"test": "flecks test"
|
||||
},
|
||||
"files": [
|
||||
"server.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@flecks/core": "^2.0.0",
|
||||
"express": "^4.18.2",
|
||||
"express-session": "^1.17.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@flecks/fleck": "^2.0.0"
|
||||
}
|
||||
}
|
62
packages/session/src/server.js
Normal file
62
packages/session/src/server.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
import {D} from '@flecks/core';
|
||||
import express from 'express';
|
||||
import expressSession from 'express-session';
|
||||
|
||||
const debug = D('@flecks/session');
|
||||
const debugSilly = debug.extend('silly');
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/core.config': () => ({
|
||||
/**
|
||||
* Set the cookie secret for session encryption.
|
||||
*
|
||||
* See: http://expressjs.com/en/resources/middleware/cookie-parser.html
|
||||
*/
|
||||
cookieSecret: (
|
||||
'Set the FLECKS_ENV__flecks_session_server__cookieSecret environment variable!'
|
||||
),
|
||||
}),
|
||||
'@flecks/core.mixin': (Flecks) => (
|
||||
class FlecksWithSession extends Flecks {
|
||||
|
||||
session;
|
||||
|
||||
}
|
||||
),
|
||||
'@flecks/web/server.request.route': (flecks) => {
|
||||
const urle = express.urlencoded({extended: true});
|
||||
return (req, res, next) => {
|
||||
urle(req, res, (error) => {
|
||||
if (error) {
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
flecks.session(req, res, (error) => {
|
||||
if (error) {
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
debugSilly('web session ID: %s', req.session.id);
|
||||
next();
|
||||
});
|
||||
});
|
||||
};
|
||||
},
|
||||
'@flecks/server.up': async (flecks) => {
|
||||
flecks.session = expressSession({
|
||||
resave: false,
|
||||
sameSite: true,
|
||||
saveUninitialized: false,
|
||||
secret: flecks.get('@flecks/session/server.cookieSecret'),
|
||||
...await flecks.invokeMergeAsync('@flecks/session.config'),
|
||||
});
|
||||
},
|
||||
'@flecks/socket/server.request.socket': (flecks) => (socket, next) => {
|
||||
flecks.session(socket.handshake, {}, () => {
|
||||
const id = socket.handshake.session?.id;
|
||||
socket.join(id);
|
||||
debugSilly('socket session ID: %s', id);
|
||||
next();
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,115 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.0.3](https://github.com/cha0s/flecks/compare/v2.0.2...v2.0.3) (2023-11-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* electron ([81fc978](https://github.com/cha0s/flecks/commit/81fc978da2b8d32e303d165fe7c2f6071ac8e741))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.2](https://github.com/cha0s/flecks/compare/v2.0.1...v2.0.2) (2023-11-22)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.1](https://github.com/cha0s/flecks/compare/v2.0.0...v2.0.1) (2023-11-22)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [2.0.0](https://github.com/cha0s/flecks/compare/v1.4.1...v2.0.0) (2023-11-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* UserRequired ([9b5f6f4](https://github.com/cha0s/flecks/commit/9b5f6f4818afaec76ee941c8d2c4795912234ee8))
|
||||
* webpack 5 support ([288b368](https://github.com/cha0s/flecks/commit/288b368b9ff96be5ccb58bd811838a4a4bb6c48c))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.4.1](https://github.com/cha0s/flecks/compare/v1.4.0...v1.4.1) (2022-03-19)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.4.0](https://github.com/cha0s/flecks/compare/v1.3.0...v1.4.0) (2022-03-19)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.3.0](https://github.com/cha0s/flecks/compare/v1.2.1...v1.3.0) (2022-03-09)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.2.1](https://github.com/cha0s/flecks/compare/v1.2.0...v1.2.1) (2022-03-08)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.2.0](https://github.com/cha0s/flecks/compare/v1.1.1...v1.2.0) (2022-03-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **user:** redux hydration ([60ab421](https://github.com/cha0s/flecks/commit/60ab4219887daa2efc12ca26e02c76287a4fd779))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* docs ([5e2b825](https://github.com/cha0s/flecks/commit/5e2b8256205efc0280c8308cea3e64fa06fe16a9))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.1.1](https://github.com/cha0s/flecks/compare/v1.1.0...v1.1.1) (2022-02-28)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [1.1.0](https://github.com/cha0s/flecks/compare/v1.0.2...v1.1.0) (2022-02-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* babel in flecksrc ([dc60217](https://github.com/cha0s/flecks/commits/dc60217bd66d436eac6afe0e6d803f43a354bc6b))
|
||||
* rich debugging ([545bfce](https://github.com/cha0s/flecks/commits/545bfce1ab602044041b370b413df62ae0cb9363))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.0.2](https://github.com/cha0s/flecks/compare/v1.0.1...v1.0.2) (2022-02-28)
|
||||
|
||||
**Note:** Version bump only for package @flecks/user
|
|
@ -1,10 +0,0 @@
|
|||
export const hooks = {
|
||||
/**
|
||||
* Modify express-session configuration.
|
||||
*
|
||||
* See: https://www.npmjs.com/package/express-session
|
||||
*/
|
||||
'@flecks/user.session': () => ({
|
||||
saveUninitialized: true,
|
||||
}),
|
||||
};
|
|
@ -1,15 +0,0 @@
|
|||
import {Logout} from './packets';
|
||||
|
||||
import {user, users} from './state';
|
||||
|
||||
export * from './state';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/redux.slices': () => ({
|
||||
user,
|
||||
users,
|
||||
}),
|
||||
'@flecks/socket.packets': (flecks) => ({
|
||||
Logout: Logout(flecks),
|
||||
}),
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
export {default as UserLocalLogin} from './user-local-login';
|
||||
export {default as UserRequired} from './user-required';
|
|
@ -1 +0,0 @@
|
|||
export * from './components';
|
|
@ -1,71 +0,0 @@
|
|||
import {randomBytes} from 'crypto';
|
||||
|
||||
import {Flecks} from '@flecks/core';
|
||||
import passport from 'passport';
|
||||
import LocalStrategy from 'passport-local';
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/core.config': () => ({
|
||||
/**
|
||||
* Path to redirect to after failed login.
|
||||
*/
|
||||
failureRedirect: '/',
|
||||
/**
|
||||
* Path to redirect to after successful login.
|
||||
*/
|
||||
successRedirect: '/',
|
||||
}),
|
||||
'@flecks/db/server.models.decorate': (
|
||||
Flecks.decorate(require.context('./models/decorators', false, /\.js$/))
|
||||
),
|
||||
'@flecks/web.routes': (flecks) => {
|
||||
const {failureRedirect, successRedirect} = flecks.get('@flecks/user/local/server');
|
||||
return [
|
||||
{
|
||||
method: 'post',
|
||||
path: '/auth/local',
|
||||
middleware: passport.authenticate('local', {failureRedirect, successRedirect}),
|
||||
},
|
||||
];
|
||||
},
|
||||
'@flecks/repl.commands': (flecks) => {
|
||||
const {User} = flecks.db.Models;
|
||||
return {
|
||||
createUser: async (spec) => {
|
||||
const [email, maybePassword] = spec.split(' ', 2);
|
||||
const password = maybePassword || randomBytes(8).toString('hex');
|
||||
const user = User.build({email});
|
||||
await user.addHashedPassword(password);
|
||||
await user.save();
|
||||
},
|
||||
resetPassword: async (email) => {
|
||||
const password = randomBytes(8).toString('hex');
|
||||
const user = await User.findOne({where: {email}});
|
||||
if (user) {
|
||||
await user.addHashedPassword(password);
|
||||
await user.save();
|
||||
return `\nNew password: ${password}\n\n`;
|
||||
}
|
||||
return 'User not found.\n';
|
||||
},
|
||||
};
|
||||
},
|
||||
'@flecks/server.up': Flecks.priority(
|
||||
(flecks) => {
|
||||
passport.use(new LocalStrategy(
|
||||
{usernameField: 'email'},
|
||||
async (email, password, fn) => {
|
||||
const {User} = flecks.db.Models;
|
||||
try {
|
||||
const user = await User.findOne({where: {email}});
|
||||
fn(undefined, user && await user.validatePassword(password) && user);
|
||||
}
|
||||
catch (error) {
|
||||
fn(error);
|
||||
}
|
||||
},
|
||||
));
|
||||
},
|
||||
{after: '@flecks/user/server', before: '@flecks/repl/server'},
|
||||
),
|
||||
};
|
|
@ -1,2 +0,0 @@
|
|||
// eslint-disable-next-line import/prefer-default-export
|
||||
export {default as Logout} from './logout';
|
|
@ -1,20 +0,0 @@
|
|||
export default (flecks) => {
|
||||
const {Packet, ValidationError} = flecks.fleck('@flecks/socket');
|
||||
|
||||
return class Logout extends Packet {
|
||||
|
||||
static respond(packet, {req}) {
|
||||
req.logout();
|
||||
return new Promise((r, e) => {
|
||||
req.session.save((error) => (error ? e(error) : r()));
|
||||
});
|
||||
}
|
||||
|
||||
static validate(packet, {req}) {
|
||||
if (!req.user) {
|
||||
throw new ValidationError({code: 400, reason: 'anonymous'});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
|
@ -1,87 +0,0 @@
|
|||
import {D, Flecks} from '@flecks/core';
|
||||
import passport from 'passport';
|
||||
import LogOps from 'passport/lib/http/request';
|
||||
|
||||
const debug = D('@flecks/user/passport');
|
||||
const debugSilly = debug.extend('silly');
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/db/server.models': Flecks.provide(require.context('./models', false, /\.js$/)),
|
||||
'@flecks/web/server.request.route': (flecks) => (req, res, next) => {
|
||||
debugSilly('@flecks/web/server.request.route: passport.initialize()');
|
||||
passport.initialize()(req, res, () => {
|
||||
debugSilly('@flecks/web/server.request.route: passport.session()');
|
||||
passport.session()(req, res, () => {
|
||||
if (!req.user) {
|
||||
const {User} = flecks.db.Models;
|
||||
req.user = new User();
|
||||
req.user.id = 0;
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
'@flecks/web.routes': () => [
|
||||
{
|
||||
method: 'get',
|
||||
path: '/auth/logout',
|
||||
middleware: (req, res) => {
|
||||
req.logout();
|
||||
res.redirect('/');
|
||||
},
|
||||
},
|
||||
],
|
||||
'@flecks/server.up': Flecks.priority(
|
||||
(flecks) => {
|
||||
passport.serializeUser((user, fn) => fn(null, user.id));
|
||||
passport.deserializeUser(async (id, fn) => {
|
||||
const {User} = flecks.db.Models;
|
||||
try {
|
||||
fn(undefined, await User.findByPk(id));
|
||||
}
|
||||
catch (error) {
|
||||
fn(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
{before: '@flecks/web/server', after: ['@flecks/db/server', '@flecks/governor/server']},
|
||||
),
|
||||
'@flecks/socket.intercom': () => ({
|
||||
'@flecks/user.users': async (sids, server) => {
|
||||
const sockets = await server.sockets();
|
||||
return sids
|
||||
.filter((sid) => sockets.has(sid))
|
||||
.reduce(
|
||||
(r, sid) => ({
|
||||
...r,
|
||||
[sid]: sockets.get(sid).handshake.user.id,
|
||||
}),
|
||||
{},
|
||||
);
|
||||
},
|
||||
}),
|
||||
'@flecks/socket/server.request.socket': Flecks.priority(
|
||||
(flecks) => (socket, next) => {
|
||||
debugSilly('@flecks/socket/server.request.socket: passport.initialize()');
|
||||
passport.initialize()(socket.handshake, undefined, () => {
|
||||
debugSilly('@flecks/socket/server.request.socket: passport.session()');
|
||||
passport.session()(socket.handshake, undefined, async () => {
|
||||
if (!socket.handshake.user) {
|
||||
const {User} = flecks.db.Models;
|
||||
socket.handshake.user = new User();
|
||||
socket.handshake.user.id = 0;
|
||||
}
|
||||
socket.handshake.login = LogOps.logIn;
|
||||
socket.handshake.logIn = LogOps.logIn;
|
||||
socket.handshake.logout = LogOps.logOut;
|
||||
socket.handshake.logOut = LogOps.logOut;
|
||||
socket.handshake.isAuthenticated = LogOps.isAuthenticated;
|
||||
socket.handshake.isUnauthenticated = LogOps.isUnauthenticated;
|
||||
await socket.join(`/u/${socket.handshake.user.id}`);
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
{before: '@flecks/governor/server'},
|
||||
),
|
||||
};
|
|
@ -1,75 +0,0 @@
|
|||
import {D, Flecks} from '@flecks/core';
|
||||
import express from 'express';
|
||||
import expressSession from 'express-session';
|
||||
|
||||
const debug = D('@flecks/user/session');
|
||||
const debugSilly = debug.extend('silly');
|
||||
|
||||
export const hooks = {
|
||||
'@flecks/core.config': () => ({
|
||||
/**
|
||||
* Set the cookie secret for session encryption.
|
||||
*
|
||||
* See: http://expressjs.com/en/resources/middleware/cookie-parser.html
|
||||
*/
|
||||
cookieSecret: (
|
||||
'Set the FLECKS_ENV__flecks_user_session_server__cookieSecret environment variable!'
|
||||
),
|
||||
}),
|
||||
'@flecks/core.mixin': (Flecks) => (
|
||||
class FlecksWithUser extends Flecks {
|
||||
|
||||
user = {
|
||||
session: undefined,
|
||||
}
|
||||
|
||||
}
|
||||
),
|
||||
'@flecks/web/server.request.route': Flecks.priority(
|
||||
(flecks) => {
|
||||
const urle = express.urlencoded({extended: true});
|
||||
return (req, res, next) => {
|
||||
debugSilly('@flecks/web/server.request.route: express.urlencoded()');
|
||||
urle(req, res, (error) => {
|
||||
if (error) {
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
debugSilly('@flecks/web/server.request.route: session()');
|
||||
flecks.user.session(req, res, (error) => {
|
||||
if (error) {
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
debugSilly('session ID: %s', req.session.id);
|
||||
next();
|
||||
});
|
||||
});
|
||||
};
|
||||
},
|
||||
{before: '@flecks/user/server'},
|
||||
),
|
||||
'@flecks/server.up': Flecks.priority(
|
||||
async (flecks) => {
|
||||
flecks.user.session = expressSession({
|
||||
resave: false,
|
||||
sameSite: true,
|
||||
saveUninitialized: false,
|
||||
secret: flecks.get('@flecks/user/session/server.cookieSecret'),
|
||||
...await flecks.invokeMergeAsync('@flecks/user.session'),
|
||||
});
|
||||
},
|
||||
{after: ['@flecks/governor/server', '@flecks/user/server']},
|
||||
),
|
||||
'@flecks/socket/server.request.socket': Flecks.priority(
|
||||
(flecks) => (socket, next) => {
|
||||
debugSilly('@flecks/socket/server.request.socket: session()');
|
||||
flecks.user.session(socket.handshake, {}, () => {
|
||||
const id = socket.handshake.session?.id;
|
||||
socket.join(id);
|
||||
next();
|
||||
});
|
||||
},
|
||||
{before: '@flecks/user/server'},
|
||||
),
|
||||
};
|
|
@ -18,11 +18,11 @@ Our `flecks.yml` could be configured like so:
|
|||
```yaml
|
||||
'@flecks/http/server':
|
||||
'request.route':
|
||||
- '@flecks/user/session'
|
||||
- '@flecks/session'
|
||||
- '@my-app/dark-mode-check'
|
||||
```
|
||||
|
||||
In this application, when `@flecks/http/server.request.route` is invoked, `@flecks/user/session`'s
|
||||
In this application, when `@flecks/http/server.request.route` is invoked, `@flecks/session`'s
|
||||
implementation is invoked (which reifies the user's session from cookies), followed by
|
||||
`@my-app/dark-mode-check`'s.
|
||||
|
||||
|
@ -38,7 +38,7 @@ provides you with the ellipses entry:
|
|||
```yaml
|
||||
'@flecks/http/server':
|
||||
'request.route':
|
||||
- '@flecks/user/session'
|
||||
- '@flecks/session'
|
||||
- '...'
|
||||
- '@my-app/finalize'
|
||||
```
|
||||
|
@ -71,7 +71,7 @@ export const hooks = {
|
|||
}
|
||||
```
|
||||
|
||||
Then this is the same implementation but configured to run after `@flecks/user/session/server`:
|
||||
Then this is the same implementation but configured to run after `@flecks/session/server`:
|
||||
|
||||
```js
|
||||
export const hooks = {
|
||||
|
@ -81,7 +81,7 @@ export const hooks = {
|
|||
// ...
|
||||
}
|
||||
},
|
||||
{after: '@flecks/user/session/server'},
|
||||
{after: '@flecks/session/server'},
|
||||
),
|
||||
}
|
||||
```
|
||||
|
|
|
@ -227,7 +227,7 @@ const result = await socket.send(['Whatever']);
|
|||
Whenever the client receives an `Action` packet, the action will be dispatched by
|
||||
the redux store.
|
||||
|
||||
- `@flecks/user` implements a `validate` acceptor method for the `Logout` packet:
|
||||
- `@flecks/passport` implements a `validate` acceptor method for the `Logout` packet:
|
||||
|
||||
```javascript
|
||||
static validate(packet, {req}) {
|
||||
|
@ -247,7 +247,7 @@ parameters:
|
|||
|
||||
### `type`
|
||||
|
||||
The type of intercom call to make (e.g. `@flecks/user.users`).
|
||||
The type of intercom call to make (e.g. `@flecks/passport.users`).
|
||||
|
||||
### `data`
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user