tachybase_todo/packages/plugins/verification/src/server/Plugin.ts

153 lines
4.2 KiB
TypeScript
Raw Normal View History

import path from 'path';
import { Context } from '@nocobase/actions';
import { Op } from '@nocobase/database';
import { HandlerType } from '@nocobase/resourcer';
import { Plugin } from '@nocobase/server';
import { Registry } from '@nocobase/utils';
import { namespace } from '.';
import initActions from './actions';
import { CODE_STATUS_UNUSED, CODE_STATUS_USED, PROVIDER_TYPE_SMS_ALIYUN } from './constants';
import { zhCN } from './locale';
import initProviders, { Provider } from './providers';
export interface Interceptor {
manual?: boolean;
expiresIn?: number;
feat: duplicator plugin (#1265) * chore: dump plugin * chore: rename plugin * chore: add duplicator into preset * chore: tmp commit * feat: restore & dump action * feat: collection dump & restore * feat: collection dump & restore * fix: dump with json type * fix: dump uischema * chore: tmp commit * chore: tmp commit * feat: restore custom collections * chore: code * fix: build * chore: tmp commit * fix: pm.generateClientFile * feat: dump with user plugins * feat: restore ignore collection * feat: ignore user with rolesUsers * chore: client plugins * refactor: restore insert sql * chore: code format * feat: restore with sequelize insert query * fix: restore json field * fix: json restore * refactor: dumper * refactor: restorer * chore: dump file name * chore: dump file name * chore: dump message * fix: restore with jsonb fields * feat: field data writer * chore: code * feat: collection group manager * feat: duplicator client * feat: duplicator panel * chore: disable duplicator ui * feat: dump with inquirer * chore: dumper * chore: collection group manager * feat: restore with inquirer * chore: comment * chore: inquirer page size * feat: warning before restore * feat: sync postgres sequence id after import collection * chore: restore checked * feat: dump with through table * feat: restore with through table * feat: restore with sequence field * chore: graph collection manager collection group * fix: dump with no column tables * fix: dump empty table * fix: force remove workdir * chore: disable throw error when sync empty table * feat: support map field restore * fix: restore from pg dumped file * fix: dump with logic field * chore: console.log * chore: collection group * chore: handle import collection error * fix: dump migrations table * feat: display custom collection title * fix: restore collection title display * fix: dump iframe html * fix: dump with postgres inhertitance * fix: dump sql * chore: export snapshot field * fix: import with sequences * fix: import sequences * fix: storage Co-authored-by: chenos <chenlinxh@gmail.com>
2023-01-08 12:45:02 +08:00
getReceiver(ctx): string;
feat: duplicator plugin (#1265) * chore: dump plugin * chore: rename plugin * chore: add duplicator into preset * chore: tmp commit * feat: restore & dump action * feat: collection dump & restore * feat: collection dump & restore * fix: dump with json type * fix: dump uischema * chore: tmp commit * chore: tmp commit * feat: restore custom collections * chore: code * fix: build * chore: tmp commit * fix: pm.generateClientFile * feat: dump with user plugins * feat: restore ignore collection * feat: ignore user with rolesUsers * chore: client plugins * refactor: restore insert sql * chore: code format * feat: restore with sequelize insert query * fix: restore json field * fix: json restore * refactor: dumper * refactor: restorer * chore: dump file name * chore: dump file name * chore: dump message * fix: restore with jsonb fields * feat: field data writer * chore: code * feat: collection group manager * feat: duplicator client * feat: duplicator panel * chore: disable duplicator ui * feat: dump with inquirer * chore: dumper * chore: collection group manager * feat: restore with inquirer * chore: comment * chore: inquirer page size * feat: warning before restore * feat: sync postgres sequence id after import collection * chore: restore checked * feat: dump with through table * feat: restore with through table * feat: restore with sequence field * chore: graph collection manager collection group * fix: dump with no column tables * fix: dump empty table * fix: force remove workdir * chore: disable throw error when sync empty table * feat: support map field restore * fix: restore from pg dumped file * fix: dump with logic field * chore: console.log * chore: collection group * chore: handle import collection error * fix: dump migrations table * feat: display custom collection title * fix: restore collection title display * fix: dump iframe html * fix: dump with postgres inhertitance * fix: dump sql * chore: export snapshot field * fix: import with sequences * fix: import sequences * fix: storage Co-authored-by: chenos <chenlinxh@gmail.com>
2023-01-08 12:45:02 +08:00
getCode?(ctx): string;
feat: duplicator plugin (#1265) * chore: dump plugin * chore: rename plugin * chore: add duplicator into preset * chore: tmp commit * feat: restore & dump action * feat: collection dump & restore * feat: collection dump & restore * fix: dump with json type * fix: dump uischema * chore: tmp commit * chore: tmp commit * feat: restore custom collections * chore: code * fix: build * chore: tmp commit * fix: pm.generateClientFile * feat: dump with user plugins * feat: restore ignore collection * feat: ignore user with rolesUsers * chore: client plugins * refactor: restore insert sql * chore: code format * feat: restore with sequelize insert query * fix: restore json field * fix: json restore * refactor: dumper * refactor: restorer * chore: dump file name * chore: dump file name * chore: dump message * fix: restore with jsonb fields * feat: field data writer * chore: code * feat: collection group manager * feat: duplicator client * feat: duplicator panel * chore: disable duplicator ui * feat: dump with inquirer * chore: dumper * chore: collection group manager * feat: restore with inquirer * chore: comment * chore: inquirer page size * feat: warning before restore * feat: sync postgres sequence id after import collection * chore: restore checked * feat: dump with through table * feat: restore with through table * feat: restore with sequence field * chore: graph collection manager collection group * fix: dump with no column tables * fix: dump empty table * fix: force remove workdir * chore: disable throw error when sync empty table * feat: support map field restore * fix: restore from pg dumped file * fix: dump with logic field * chore: console.log * chore: collection group * chore: handle import collection error * fix: dump migrations table * feat: display custom collection title * fix: restore collection title display * fix: dump iframe html * fix: dump with postgres inhertitance * fix: dump sql * chore: export snapshot field * fix: import with sequences * fix: import sequences * fix: storage Co-authored-by: chenos <chenlinxh@gmail.com>
2023-01-08 12:45:02 +08:00
validate?(ctx: Context, receiver: string): boolean | Promise<boolean>;
}
export default class VerificationPlugin extends Plugin {
providers: Registry<typeof Provider> = new Registry();
interceptors: Registry<Interceptor> = new Registry();
intercept: HandlerType = async (context, next) => {
const { resourceName, actionName, values } = context.action.params;
const key = `${resourceName}:${actionName}`;
const interceptor = this.interceptors.get(key);
if (!interceptor) {
return context.throw(400);
}
const receiver = interceptor.getReceiver(context);
const content = interceptor.getCode ? interceptor.getCode(context) : values.code;
if (!receiver || !content) {
return context.throw(400);
}
// check if code match, then call next
// find the code based on action params
const VerificationRepo = this.db.getRepository('verifications');
const item = await VerificationRepo.findOne({
filter: {
receiver,
type: key,
content,
expiresAt: {
[Op.gt]: new Date(),
},
status: CODE_STATUS_UNUSED,
},
});
if (!item) {
feat: duplicator plugin (#1265) * chore: dump plugin * chore: rename plugin * chore: add duplicator into preset * chore: tmp commit * feat: restore & dump action * feat: collection dump & restore * feat: collection dump & restore * fix: dump with json type * fix: dump uischema * chore: tmp commit * chore: tmp commit * feat: restore custom collections * chore: code * fix: build * chore: tmp commit * fix: pm.generateClientFile * feat: dump with user plugins * feat: restore ignore collection * feat: ignore user with rolesUsers * chore: client plugins * refactor: restore insert sql * chore: code format * feat: restore with sequelize insert query * fix: restore json field * fix: json restore * refactor: dumper * refactor: restorer * chore: dump file name * chore: dump file name * chore: dump message * fix: restore with jsonb fields * feat: field data writer * chore: code * feat: collection group manager * feat: duplicator client * feat: duplicator panel * chore: disable duplicator ui * feat: dump with inquirer * chore: dumper * chore: collection group manager * feat: restore with inquirer * chore: comment * chore: inquirer page size * feat: warning before restore * feat: sync postgres sequence id after import collection * chore: restore checked * feat: dump with through table * feat: restore with through table * feat: restore with sequence field * chore: graph collection manager collection group * fix: dump with no column tables * fix: dump empty table * fix: force remove workdir * chore: disable throw error when sync empty table * feat: support map field restore * fix: restore from pg dumped file * fix: dump with logic field * chore: console.log * chore: collection group * chore: handle import collection error * fix: dump migrations table * feat: display custom collection title * fix: restore collection title display * fix: dump iframe html * fix: dump with postgres inhertitance * fix: dump sql * chore: export snapshot field * fix: import with sequences * fix: import sequences * fix: storage Co-authored-by: chenos <chenlinxh@gmail.com>
2023-01-08 12:45:02 +08:00
return context.throw(400, {
code: 'InvalidVerificationCode',
message: context.t('Verification code is invalid', { ns: namespace }),
});
}
// TODO: code should be removed if exists in values
// context.action.mergeParams({
// values: {
// }
// });
await next();
// or delete
await item.update({
status: CODE_STATUS_USED,
});
};
async install() {
const {
DEFAULT_SMS_VERIFY_CODE_PROVIDER,
INIT_ALI_SMS_ACCESS_KEY,
INIT_ALI_SMS_ACCESS_KEY_SECRET,
INIT_ALI_SMS_ENDPOINT = 'dysmsapi.aliyuncs.com',
INIT_ALI_SMS_VERIFY_CODE_TEMPLATE,
INIT_ALI_SMS_VERIFY_CODE_SIGN,
} = process.env;
if (
DEFAULT_SMS_VERIFY_CODE_PROVIDER &&
INIT_ALI_SMS_ACCESS_KEY &&
INIT_ALI_SMS_ACCESS_KEY_SECRET &&
INIT_ALI_SMS_VERIFY_CODE_TEMPLATE &&
INIT_ALI_SMS_VERIFY_CODE_SIGN
) {
const ProviderRepo = this.db.getRepository('verifications_providers');
await ProviderRepo.create({
values: {
id: DEFAULT_SMS_VERIFY_CODE_PROVIDER,
type: PROVIDER_TYPE_SMS_ALIYUN,
title: 'Default SMS sender',
options: {
accessKeyId: INIT_ALI_SMS_ACCESS_KEY,
accessKeySecret: INIT_ALI_SMS_ACCESS_KEY_SECRET,
endpoint: INIT_ALI_SMS_ENDPOINT,
sign: INIT_ALI_SMS_VERIFY_CODE_SIGN,
template: INIT_ALI_SMS_VERIFY_CODE_TEMPLATE,
},
feat: duplicator plugin (#1265) * chore: dump plugin * chore: rename plugin * chore: add duplicator into preset * chore: tmp commit * feat: restore & dump action * feat: collection dump & restore * feat: collection dump & restore * fix: dump with json type * fix: dump uischema * chore: tmp commit * chore: tmp commit * feat: restore custom collections * chore: code * fix: build * chore: tmp commit * fix: pm.generateClientFile * feat: dump with user plugins * feat: restore ignore collection * feat: ignore user with rolesUsers * chore: client plugins * refactor: restore insert sql * chore: code format * feat: restore with sequelize insert query * fix: restore json field * fix: json restore * refactor: dumper * refactor: restorer * chore: dump file name * chore: dump file name * chore: dump message * fix: restore with jsonb fields * feat: field data writer * chore: code * feat: collection group manager * feat: duplicator client * feat: duplicator panel * chore: disable duplicator ui * feat: dump with inquirer * chore: dumper * chore: collection group manager * feat: restore with inquirer * chore: comment * chore: inquirer page size * feat: warning before restore * feat: sync postgres sequence id after import collection * chore: restore checked * feat: dump with through table * feat: restore with through table * feat: restore with sequence field * chore: graph collection manager collection group * fix: dump with no column tables * fix: dump empty table * fix: force remove workdir * chore: disable throw error when sync empty table * feat: support map field restore * fix: restore from pg dumped file * fix: dump with logic field * chore: console.log * chore: collection group * chore: handle import collection error * fix: dump migrations table * feat: display custom collection title * fix: restore collection title display * fix: dump iframe html * fix: dump with postgres inhertitance * fix: dump sql * chore: export snapshot field * fix: import with sequences * fix: import sequences * fix: storage Co-authored-by: chenos <chenlinxh@gmail.com>
2023-01-08 12:45:02 +08:00
default: true,
},
});
}
}
async load() {
const { app, db, options } = this;
app.i18n.addResources('zh-CN', namespace, zhCN);
feat: duplicator plugin (#1265) * chore: dump plugin * chore: rename plugin * chore: add duplicator into preset * chore: tmp commit * feat: restore & dump action * feat: collection dump & restore * feat: collection dump & restore * fix: dump with json type * fix: dump uischema * chore: tmp commit * chore: tmp commit * feat: restore custom collections * chore: code * fix: build * chore: tmp commit * fix: pm.generateClientFile * feat: dump with user plugins * feat: restore ignore collection * feat: ignore user with rolesUsers * chore: client plugins * refactor: restore insert sql * chore: code format * feat: restore with sequelize insert query * fix: restore json field * fix: json restore * refactor: dumper * refactor: restorer * chore: dump file name * chore: dump file name * chore: dump message * fix: restore with jsonb fields * feat: field data writer * chore: code * feat: collection group manager * feat: duplicator client * feat: duplicator panel * chore: disable duplicator ui * feat: dump with inquirer * chore: dumper * chore: collection group manager * feat: restore with inquirer * chore: comment * chore: inquirer page size * feat: warning before restore * feat: sync postgres sequence id after import collection * chore: restore checked * feat: dump with through table * feat: restore with through table * feat: restore with sequence field * chore: graph collection manager collection group * fix: dump with no column tables * fix: dump empty table * fix: force remove workdir * chore: disable throw error when sync empty table * feat: support map field restore * fix: restore from pg dumped file * fix: dump with logic field * chore: console.log * chore: collection group * chore: handle import collection error * fix: dump migrations table * feat: display custom collection title * fix: restore collection title display * fix: dump iframe html * fix: dump with postgres inhertitance * fix: dump sql * chore: export snapshot field * fix: import with sequences * fix: import sequences * fix: storage Co-authored-by: chenos <chenlinxh@gmail.com>
2023-01-08 12:45:02 +08:00
await this.importCollections(path.resolve(__dirname, 'collections'));
initProviders(this);
initActions(this);
// add middleware to action
app.resourcer.use(async (context, next) => {
const { resourceName, actionName, values } = context.action.params;
const key = `${resourceName}:${actionName}`;
const interceptor = this.interceptors.get(key);
if (!interceptor || interceptor.manual) {
return next();
}
return this.intercept(context, next);
});
app.acl.allow('verifications', 'create');
app.acl.allow('verifications_providers', '*', 'allowConfigure');
}
async getDefault() {
const providerRepo = this.db.getRepository('verifications_providers');
return providerRepo.findOne({
filter: {
default: true,
feat: duplicator plugin (#1265) * chore: dump plugin * chore: rename plugin * chore: add duplicator into preset * chore: tmp commit * feat: restore & dump action * feat: collection dump & restore * feat: collection dump & restore * fix: dump with json type * fix: dump uischema * chore: tmp commit * chore: tmp commit * feat: restore custom collections * chore: code * fix: build * chore: tmp commit * fix: pm.generateClientFile * feat: dump with user plugins * feat: restore ignore collection * feat: ignore user with rolesUsers * chore: client plugins * refactor: restore insert sql * chore: code format * feat: restore with sequelize insert query * fix: restore json field * fix: json restore * refactor: dumper * refactor: restorer * chore: dump file name * chore: dump file name * chore: dump message * fix: restore with jsonb fields * feat: field data writer * chore: code * feat: collection group manager * feat: duplicator client * feat: duplicator panel * chore: disable duplicator ui * feat: dump with inquirer * chore: dumper * chore: collection group manager * feat: restore with inquirer * chore: comment * chore: inquirer page size * feat: warning before restore * feat: sync postgres sequence id after import collection * chore: restore checked * feat: dump with through table * feat: restore with through table * feat: restore with sequence field * chore: graph collection manager collection group * fix: dump with no column tables * fix: dump empty table * fix: force remove workdir * chore: disable throw error when sync empty table * feat: support map field restore * fix: restore from pg dumped file * fix: dump with logic field * chore: console.log * chore: collection group * chore: handle import collection error * fix: dump migrations table * feat: display custom collection title * fix: restore collection title display * fix: dump iframe html * fix: dump with postgres inhertitance * fix: dump sql * chore: export snapshot field * fix: import with sequences * fix: import sequences * fix: storage Co-authored-by: chenos <chenlinxh@gmail.com>
2023-01-08 12:45:02 +08:00
},
});
}
}