0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

Provide OIDC jwk and reorg code

This commit is contained in:
Gao Sun 2021-06-27 20:44:05 +08:00
parent 65cd21377c
commit 469256f93a
No known key found for this signature in database
GPG key ID: 0F0EFA2E36639F31
8 changed files with 119 additions and 78 deletions

View file

@ -20,7 +20,7 @@
"koa-mount": "^4.0.0",
"koa-router": "^10.0.0",
"oidc-provider": "^7.4.1",
"slonik": "23.6.3",
"slonik": "^23.8.1",
"slonik-interceptor-preset": "^1.2.10"
},
"devDependencies": {

View file

@ -1,8 +1,9 @@
import { createPool } from 'slonik';
import { createInterceptors } from 'slonik-interceptor-preset';
import { getEnv } from '../utils';
const interceptors = [...createInterceptors()];
const pool = createPool('postgres://localhost/logto', { interceptors });
const pool = createPool(getEnv('DB_URL'), { interceptors });
export default pool;

View file

@ -2,54 +2,16 @@ import dotenv from 'dotenv';
dotenv.config();
import Koa from 'koa';
import logger from 'koa-logger';
import mount from 'koa-mount';
import Router from 'koa-router';
import { Provider } from 'oidc-provider';
import postgresAdapter from './oidc/adapter';
const router = new Router();
import initApp from './init';
import { getEnv } from './utils';
const app = new Koa();
const PORT = 3000;
const port = Number(getEnv('PORT', '3000'));
const oidc = new Provider(`http://localhost:${PORT}/oidc`, {
adapter: postgresAdapter,
renderError: (ctx, out, error) => {
console.log(error);
},
cookies: {
// V2: Rotate this when necessary
// https://github.com/panva/node-oidc-provider/blob/main/docs/README.md#cookieskeys
keys: ['LOGTOSEKRIT1'],
},
clients: [
{
client_id: 'foo',
redirect_uris: ['http://localhost:3000/callback'],
grant_types: ['authorization_code', 'refresh_token'],
token_endpoint_auth_method: 'none',
},
],
findAccount: (ctx, sub) => {
console.log('finding account');
return {
accountId: sub,
claims: async (use, scope, claims) => {
console.log('claims', use, scope, claims);
return { sub };
},
};
},
});
router.get('/callback', (ctx) => {
ctx.body = 'A callback';
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
app.use(logger()).use(mount('/oidc', oidc.app)).use(router.routes()).use(router.allowedMethods());
app.listen(PORT, () => {
console.log(`App is listening on port ${PORT}`);
});
(async () => {
try {
await initApp(app, port);
} catch (error: unknown) {
console.log('Error while initializing app', error);
}
})();

View file

@ -0,0 +1,16 @@
import Koa from 'koa';
import logger from 'koa-logger';
import initOidc from './oidc';
import initRouter from './router';
export default async function initApp(app: Koa, port: number): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
app.use(logger());
await initOidc(app, port);
initRouter(app);
app.listen(port, () => {
console.log(`App is listening on port ${port}`);
});
}

View file

@ -0,0 +1,48 @@
import crypto from 'crypto';
import Koa from 'koa';
import mount from 'koa-mount';
import { Provider } from 'oidc-provider';
import postgresAdapter from '../oidc/adapter';
import { fromKeyLike } from 'jose/jwk/from_key_like';
import { getEnv } from '../utils';
export default async function initOidc(app: Koa, port: number): Promise<void> {
const privateKey = crypto.createPrivateKey(
Buffer.from(getEnv('OIDC_PROVIDER_PRIVATE_KEY_BASE64'), 'base64')
);
const keys = [await fromKeyLike(privateKey)];
const oidc = new Provider(`http://localhost:${port}/oidc`, {
adapter: postgresAdapter,
renderError: (ctx, out, error) => {
console.log(error);
},
cookies: {
// V2: Rotate this when necessary
// https://github.com/panva/node-oidc-provider/blob/main/docs/README.md#cookieskeys
keys: ['LOGTOSEKRIT1'],
},
jwks: {
keys,
},
clients: [
{
client_id: 'foo',
redirect_uris: ['http://localhost:3000/callback'],
grant_types: ['authorization_code', 'refresh_token'],
token_endpoint_auth_method: 'none',
},
],
findAccount: (ctx, sub) => {
console.log('finding account');
return {
accountId: sub,
claims: async (use, scope, claims) => {
console.log('claims', use, scope, claims);
return { sub };
},
};
},
});
app.use(mount('/oidc', oidc.app));
}

View file

@ -0,0 +1,12 @@
import Koa from 'koa';
import Router from 'koa-router';
const router = new Router();
router.get('/callback', (ctx) => {
ctx.body = 'A callback';
});
export default function initRouter(app: Koa): void {
app.use(router.routes()).use(router.allowedMethods());
}

View file

@ -3,3 +3,5 @@ export type Falsy = 0 | undefined | null | false | '';
export const conditional = <T>(value: T | Falsy): Optional<T> => (value ? value : undefined);
export const conditionalString = (value: string | Falsy): string => (value ? value : '');
export const getEnv = (key: string, fallback = ''): string => process.env[key] ?? fallback;

View file

@ -3940,7 +3940,7 @@ pg-copy-streams@^5.1.1:
dependencies:
obuf "^1.1.2"
pg-cursor@^2.4.1, pg-cursor@^2.5.2:
pg-cursor@^2.4.1, pg-cursor@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/pg-cursor/-/pg-cursor-2.6.0.tgz#a85df1bd1389c75ffa443ee94073da0a1be360ba"
integrity sha512-BFLg40CTgBJ+LX9EwqjztUYaKxpxLffMmDTmlQNMCustX/JxMTYimxRkdhZvPYZGp++/2LjuqkKtO5DVVq0FNg==
@ -3995,7 +3995,7 @@ pg-types@^3.0.1:
postgres-date "~1.0.4"
postgres-interval "^1.1.0"
pg@^8.4.1, pg@^8.5.1:
pg@^8.4.1, pg@^8.6.0:
version "8.6.0"
resolved "https://registry.yarnpkg.com/pg/-/pg-8.6.0.tgz#e222296b0b079b280cce106ea991703335487db2"
integrity sha512-qNS9u61lqljTDFvmk/N66EeGq3n6Ujzj0FFyNMGQr6XuEv4tgNTXvJQTfJdcvGit5p5/DWPu+wj920hAJFI+QQ==
@ -4427,7 +4427,7 @@ roarr@^2.15.4:
semver-compare "^1.0.0"
sprintf-js "^1.1.2"
roarr@^4.2.0:
roarr@^4.2.5:
version "4.2.5"
resolved "https://registry.yarnpkg.com/roarr/-/roarr-4.2.5.tgz#b4e5ddba4ef40ce66fbef0dc57cf9c584687a7cb"
integrity sha512-ZSs1hr2gyWickWDr2Yw0qcuef+EJKwZtNxUj7poxvIDxVq+ZvQreVNdPVLHonWpavBeZaOcAGVFV5xM/HqRR8g==
@ -4520,7 +4520,7 @@ serialize-error@^7.0.1:
dependencies:
type-fest "^0.13.1"
serialize-error@^8.0.1:
serialize-error@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67"
integrity sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==
@ -4646,30 +4646,6 @@ slonik-interceptor-query-normalisation@^1.1.10:
core-js "^3.6.4"
slonik "^22.4.0"
slonik@23.6.3:
version "23.6.3"
resolved "https://registry.yarnpkg.com/slonik/-/slonik-23.6.3.tgz#84c7853463d9980f8efc92ca90c3389d838e639a"
integrity sha512-o+GtTFfXDYf5m1Hx2Bz1mGHxk6VRGOxALg6Arr6vVfQu//ua6j9YI/0/O21ul1LP0wIQTrdmpzoma3qAfhXTOQ==
dependencies:
concat-stream "^2.0.0"
delay "^5.0.0"
es6-error "^4.1.1"
get-stack-trace "^2.0.3"
hyperid "^2.1.0"
is-plain-object "^5.0.0"
iso8601-duration "^1.3.0"
pg "^8.5.1"
pg-connection-string "^2.4.0"
pg-copy-streams "^5.1.1"
pg-copy-streams-binary "^2.0.1"
pg-cursor "^2.5.2"
postgres-array "^3.0.1"
postgres-interval "^3.0.0"
promise-deferred "^2.0.3"
roarr "^4.2.0"
serialize-error "^8.0.1"
through2 "^4.0.2"
slonik@^22.4.0:
version "22.7.1"
resolved "https://registry.yarnpkg.com/slonik/-/slonik-22.7.1.tgz#46326b3050f3e466918a7db3eacc62dc40834ea5"
@ -4695,6 +4671,30 @@ slonik@^22.4.0:
through2 "^4.0.2"
ulid "^2.3.0"
slonik@^23.8.1:
version "23.8.1"
resolved "https://registry.yarnpkg.com/slonik/-/slonik-23.8.1.tgz#594016f5fa8755fa95b1e295dec2eefe94c8e05d"
integrity sha512-TUWOddia5kNfI641EPeo4AMBwBXb+IfW2zgHKULcc2+rOtL6toM6EBGoxAbMrfgI0Djku/+Fkui+Uo1mi8KGoA==
dependencies:
concat-stream "^2.0.0"
delay "^5.0.0"
es6-error "^4.1.1"
get-stack-trace "^2.0.3"
hyperid "^2.1.0"
is-plain-object "^5.0.0"
iso8601-duration "^1.3.0"
pg "^8.6.0"
pg-connection-string "^2.5.0"
pg-copy-streams "^5.1.1"
pg-copy-streams-binary "^2.0.1"
pg-cursor "^2.6.0"
postgres-array "^3.0.1"
postgres-interval "^3.0.0"
promise-deferred "^2.0.3"
roarr "^4.2.5"
serialize-error "^8.1.0"
through2 "^4.0.2"
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"