sequelize.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * This is a very rough-edged example, the idea is to still work with the fact that oidc-provider
  3. * has a rather "dynamic" schema. This example uses sequelize with postgresql, and all dynamic data
  4. * uses JSON fields. id is set to be the primary key, grantId should be additionaly indexed for
  5. * models where these fields are set (grantId-able models). userCode should be additionaly indexed
  6. * for DeviceCode model. uid should be additionaly indexed for Session model. For sequelize
  7. * migrations @see https://github.com/Rogger794/node-oidc-provider/tree/examples/example/migrations/sequelize
  8. */
  9. // npm i sequelize@^5.21.2
  10. const Sequelize = require('sequelize'); // eslint-disable-line import/no-unresolved
  11. const sequelize = new Sequelize('seec_sso', 'root', '981018', {
  12. host: 'localhost',
  13. port: 3306,
  14. dialect: 'mysql',
  15. });
  16. const grantable = new Set([
  17. 'AccessToken',
  18. 'AuthorizationCode',
  19. 'RefreshToken',
  20. 'DeviceCode',
  21. ]);
  22. const models = [
  23. 'Session',
  24. 'AccessToken',
  25. 'AuthorizationCode',
  26. 'RefreshToken',
  27. 'DeviceCode',
  28. 'ClientCredentials',
  29. 'Client',
  30. 'InitialAccessToken',
  31. 'RegistrationAccessToken',
  32. 'Interaction',
  33. 'ReplayDetection',
  34. 'PushedAuthorizationRequest',
  35. ].reduce((map, name) => {
  36. map.set(name, sequelize.define(name, {
  37. id: { type: Sequelize.STRING, primaryKey: true },
  38. ...(grantable.has(name) ? { grantId: { type: Sequelize.STRING } } : undefined),
  39. ...(name === 'DeviceCode' ? { userCode: { type: Sequelize.STRING } } : undefined),
  40. ...(name === 'Session' ? { uid: { type: Sequelize.STRING } } : undefined),
  41. data: { type: Sequelize.JSONB },
  42. expiresAt: { type: Sequelize.DATE },
  43. consumedAt: { type: Sequelize.DATE },
  44. }));
  45. return map;
  46. }, new Map());
  47. class SequelizeAdapter {
  48. constructor(name) {
  49. this.model = models.get(name);
  50. this.name = name;
  51. }
  52. async upsert(id, data, expiresIn) {
  53. await this.model.upsert({
  54. id,
  55. data,
  56. ...(data.grantId ? { grantId: data.grantId } : undefined),
  57. ...(data.userCode ? { userCode: data.userCode } : undefined),
  58. ...(data.uid ? { uid: data.uid } : undefined),
  59. ...(expiresIn ? { expiresAt: new Date(Date.now() + (expiresIn * 1000)) } : undefined),
  60. });
  61. }
  62. async find(id) {
  63. const found = await this.model.findByPk(id);
  64. if (!found) return undefined;
  65. return {
  66. ...found.data,
  67. ...(found.consumedAt ? { consumed: true } : undefined),
  68. };
  69. }
  70. async findByUserCode(userCode) {
  71. const found = await this.model.findOne({ where: { userCode } });
  72. if (!found) return undefined;
  73. return {
  74. ...found.data,
  75. ...(found.consumedAt ? { consumed: true } : undefined),
  76. };
  77. }
  78. async findByUid(uid) {
  79. const found = await this.model.findOne({ where: { uid } });
  80. if (!found) return undefined;
  81. return {
  82. ...found.data,
  83. ...(found.consumedAt ? { consumed: true } : undefined),
  84. };
  85. }
  86. async destroy(id) {
  87. await this.model.destroy({ where: { id } });
  88. }
  89. async consume(id) {
  90. await this.model.update({ consumedAt: new Date() }, { where: { id } });
  91. }
  92. async revokeByGrantId(grantId) {
  93. await this.model.destroy({ where: { grantId } });
  94. }
  95. static async connect() {
  96. return sequelize.sync();
  97. }
  98. }
  99. module.exports = SequelizeAdapter;