creating new apps, instances and users now working
This commit is contained in:
parent
2781a9fabb
commit
60deb10b45
|
@ -1 +1 @@
|
||||||
Subproject commit 11c29ab2c467ea7aea0161f331dab07694ccd0ab
|
Subproject commit 804483d3a3210936743f3b57a032783296eab06c
|
|
@ -3,8 +3,8 @@ const fs = require("fs");
|
||||||
const {join} = require("path");
|
const {join} = require("path");
|
||||||
|
|
||||||
const readFile = promisify(fs.readFile);
|
const readFile = promisify(fs.readFile);
|
||||||
const writeFile = (path, content) =>
|
const writeFile = (path, content, overwrite) =>
|
||||||
promisify(fs.writeFile)(path, content, "utf8");
|
promisify(fs.writeFile)(path, content, {encoding:"utf8", flag: overwrite ? "w" : "wx"});
|
||||||
const access = promisify(fs.access);
|
const access = promisify(fs.access);
|
||||||
const mkdir = promisify(fs.mkdir);
|
const mkdir = promisify(fs.mkdir);
|
||||||
const rmdir = promisify(fs.rmdir);
|
const rmdir = promisify(fs.rmdir);
|
||||||
|
@ -16,10 +16,16 @@ const stat = promisify(fs.stat);
|
||||||
const updateFile = root => async (path, file) =>
|
const updateFile = root => async (path, file) =>
|
||||||
await writeFile(
|
await writeFile(
|
||||||
join(root,path),
|
join(root,path),
|
||||||
file
|
file,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
const createFile = updateFile;
|
const createFile = root => async (path, file) =>
|
||||||
|
await writeFile(
|
||||||
|
join(root,path),
|
||||||
|
file,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
const loadFile = root => async (path) =>
|
const loadFile = root => async (path) =>
|
||||||
await readFile(
|
await readFile(
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
"type": "record",
|
"type": "record",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": "unique_name",
|
"name": "name",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"typeOptions": {
|
"typeOptions": {
|
||||||
"maxLength": 200,
|
"maxLength": 200,
|
||||||
|
@ -329,7 +329,7 @@
|
||||||
{
|
{
|
||||||
"name": "user_name_lookup",
|
"name": "user_name_lookup",
|
||||||
"type": "index",
|
"type": "index",
|
||||||
"map": "return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};",
|
"map": "return ({name:record.name, instanceKey:record.instance.key ? record.instance.key : '', instanceDatastoreConfig:record.instance.datastoreconfig ? record.instance.datastoreconfig : 'nothing'});",
|
||||||
"filter": "",
|
"filter": "",
|
||||||
"indexType": "ancestor",
|
"indexType": "ancestor",
|
||||||
"getShardName": "return record.name.substring(0,2)",
|
"getShardName": "return record.name.substring(0,2)",
|
||||||
|
@ -448,8 +448,8 @@
|
||||||
{
|
{
|
||||||
"actionName": "initialise_instance",
|
"actionName": "initialise_instance",
|
||||||
"eventName": "recordApi:save:onRecordCreated",
|
"eventName": "recordApi:save:onRecordCreated",
|
||||||
"optionsCreator": "return { instance:context.record, apis };",
|
"optionsCreator": "return ({ instance:context.record, apis });",
|
||||||
"condition": "record.type === \"instance\""
|
"condition": "context.record.type === \"instance\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"actionName": "create_user",
|
"actionName": "create_user",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const { tmpdir } = require("os");
|
const { tmpdir } = require("os");
|
||||||
const { join } = require("path");
|
const { join } = require("path");
|
||||||
const uuid = require("uuid/v1");
|
const uuid = require("uuid/v1");
|
||||||
const { take, takeRight } = require("lodash/fp");
|
const { take, takeRight, last } = require("lodash/fp");
|
||||||
const { splitKey, $, joinKey } = require("budibase-core").common;
|
const { splitKey, $, joinKey } = require("budibase-core").common;
|
||||||
const { unzipTarGzPackageToRuntime } = require("../../utilities/targzAppPackage");
|
const { unzipTarGzPackageToRuntime } = require("../../utilities/targzAppPackage");
|
||||||
const { getRuntimePackageDirectory } = require("../../utilities/runtimePackages");
|
const { getRuntimePackageDirectory } = require("../../utilities/runtimePackages");
|
||||||
|
@ -32,24 +32,25 @@ module.exports = (config) => {
|
||||||
|
|
||||||
const versionId = $(instance.version.key, [
|
const versionId = $(instance.version.key, [
|
||||||
splitKey,
|
splitKey,
|
||||||
takeRight(1),
|
last
|
||||||
joinKey
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const runtimeDir = getRuntimePackageDirectory(
|
const runtimeDir = getRuntimePackageDirectory(
|
||||||
application.name,
|
application.name,
|
||||||
versionId);
|
versionId);
|
||||||
|
|
||||||
if(!await exists(runtimeDir))
|
if(!await exists(runtimeDir))
|
||||||
await downloadAppPackage(apis, instance, application.name, versionId);
|
await downloadAppPackage(apis, instance, application.name, versionId);
|
||||||
|
|
||||||
instance.datastoreconfig = JSON.stringify(dbConfig);
|
instance.datastoreconfig = JSON.stringify(dbConfig);
|
||||||
instance.isNew = false;
|
instance.isNew = false;
|
||||||
await apis.recordApi.save(instance);
|
instance.transactionId = "";
|
||||||
|
|
||||||
|
await apis.recordApi.save(instance);
|
||||||
},
|
},
|
||||||
|
|
||||||
createNewUser: async ({user, apis}) => {
|
createNewUser: async ({user, apis}) => {
|
||||||
const instance = apis.recordApi.load(user.instance.key);
|
const instance = await apis.recordApi.load(user.instance.key);
|
||||||
|
|
||||||
const appKey = $(instance.key, [
|
const appKey = $(instance.key, [
|
||||||
splitKey,
|
splitKey,
|
||||||
|
@ -61,16 +62,17 @@ module.exports = (config) => {
|
||||||
|
|
||||||
const versionId = $(instance.version.key, [
|
const versionId = $(instance.version.key, [
|
||||||
splitKey,
|
splitKey,
|
||||||
takeRight(1),
|
last,
|
||||||
joinKey
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const appPackage = applictionVersionPackage(
|
const appPackage = applictionVersionPackage(
|
||||||
|
config,
|
||||||
application.name,
|
application.name,
|
||||||
versionId);
|
versionId);
|
||||||
|
|
||||||
const instanceApis = getApisWithFullAccess(
|
const instanceApis = await getApisWithFullAccess(
|
||||||
datastoreModule.getDatastore(instance.datastoreconfig),
|
datastoreModule.getDatastore(
|
||||||
|
JSON.parse(instance.datastoreconfig)),
|
||||||
appPackage);
|
appPackage);
|
||||||
|
|
||||||
const authUser = instanceApis.authApi.getNewUser();
|
const authUser = instanceApis.authApi.getNewUser();
|
||||||
|
|
|
@ -325,10 +325,10 @@
|
||||||
{
|
{
|
||||||
"name": "user_name_lookup",
|
"name": "user_name_lookup",
|
||||||
"type": "index",
|
"type": "index",
|
||||||
"map": "return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};",
|
"map": "return {name:record.unique_name, instanceDatastoreConfig:instance.datastoreconfig};",
|
||||||
"filter": "",
|
"filter": "",
|
||||||
"indexType": "ancestor",
|
"indexType": "ancestor",
|
||||||
"getShardName": "return record.name.substring(0,2)",
|
"getShardName": "return record.unique_name.substring(0,2)",
|
||||||
"getSortKey": "record.id",
|
"getSortKey": "record.id",
|
||||||
"aggregateGroups": [],
|
"aggregateGroups": [],
|
||||||
"allowedRecordNodeIds": [
|
"allowedRecordNodeIds": [
|
||||||
|
@ -438,7 +438,7 @@
|
||||||
{
|
{
|
||||||
"actionName": "output_to_file",
|
"actionName": "output_to_file",
|
||||||
"eventName": "authApi:createUser:onComplete",
|
"eventName": "authApi:createUser:onComplete",
|
||||||
"optionsCreator": "return { filename: filename:'tempaccess' + context.user.name, content:context.result.tempCode };",
|
"optionsCreator": "return { filename:'tempaccess' + context.user.name, content:context.result.tempCode };",
|
||||||
"condition": ""
|
"condition": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Binary file not shown.
|
@ -165,6 +165,21 @@ module.exports = (config, app) => {
|
||||||
);
|
);
|
||||||
ctx.response.status = StatusCodes.OK;
|
ctx.response.status = StatusCodes.OK;
|
||||||
})
|
})
|
||||||
|
.get("/:appname/api/lookup_field/*", async (ctx) => {
|
||||||
|
const recordKey = getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
const fields = ctx.query.fields.split(",")
|
||||||
|
const recordContext = await ctx.instance.recordApi.getContext(
|
||||||
|
recordKey
|
||||||
|
);
|
||||||
|
const allContext = [];
|
||||||
|
for(let field of fields) {
|
||||||
|
allContext.push(
|
||||||
|
await recordContext.referenceOptions(field)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ctx.body = allContext;
|
||||||
|
ctx.response.status = StatusCodes.OK;
|
||||||
|
})
|
||||||
.get("/:appname/api/record/*", async (ctx) => {
|
.get("/:appname/api/record/*", async (ctx) => {
|
||||||
ctx.body = await ctx.instance.recordApi.load(
|
ctx.body = await ctx.instance.recordApi.load(
|
||||||
getRecordKey(ctx.params.appname, ctx.request.path)
|
getRecordKey(ctx.params.appname, ctx.request.path)
|
||||||
|
@ -198,8 +213,9 @@ module.exports = (config, app) => {
|
||||||
|
|
||||||
const getRecordKey = (appname, wholePath) =>
|
const getRecordKey = (appname, wholePath) =>
|
||||||
wholePath
|
wholePath
|
||||||
.replace(`/${appname}/api/record/`, "")
|
.replace(`/${appname}/api/files/`, "")
|
||||||
.replace(`/${appname}/api/files/`, "");
|
.replace(`/${appname}/api/lookup_field/`, "")
|
||||||
|
.replace(`/${appname}/api/record/`, "");
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,445 @@
|
||||||
|
{
|
||||||
|
"hierarchy": {
|
||||||
|
"name": "root",
|
||||||
|
"type": "root",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"name": "application",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 500,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "Name",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "domain",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 500,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "domain",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "application_resolve_strategy",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 100,
|
||||||
|
"values": [
|
||||||
|
"domain",
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"allowDeclaredValuesOnly": true
|
||||||
|
},
|
||||||
|
"label": "Resolve Application By",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"name": "user",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "unique_name",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 200,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "Name (unique)",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "active",
|
||||||
|
"type": "bool",
|
||||||
|
"typeOptions": {
|
||||||
|
"allowNulls": false
|
||||||
|
},
|
||||||
|
"label": "Is Active",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "instance",
|
||||||
|
"type": "reference",
|
||||||
|
"typeOptions": {
|
||||||
|
"indexNodeKey": "/applications/1-{id}/allinstances",
|
||||||
|
"reverseIndexNodeKeys": [
|
||||||
|
"/applications/1-{id}/instances/2-{id}/users_on_this_instance"
|
||||||
|
],
|
||||||
|
"displayValue": "name"
|
||||||
|
},
|
||||||
|
"label": "Instance",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"children": [],
|
||||||
|
"validationRules": [],
|
||||||
|
"nodeId": 8,
|
||||||
|
"indexes": [],
|
||||||
|
"allidsShardFactor": "64",
|
||||||
|
"collectionName": "users",
|
||||||
|
"isSingle": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "instance",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 1000,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "Name",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "active",
|
||||||
|
"type": "bool",
|
||||||
|
"typeOptions": {
|
||||||
|
"allowNulls": false
|
||||||
|
},
|
||||||
|
"label": "Is Active",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "version",
|
||||||
|
"type": "reference",
|
||||||
|
"typeOptions": {
|
||||||
|
"indexNodeKey": "/applications/1-{id}/all_versions",
|
||||||
|
"reverseIndexNodeKeys": [
|
||||||
|
"/applications/1-{id}/versions/3-{id}/instances_on_this_version"
|
||||||
|
],
|
||||||
|
"displayValue": "name"
|
||||||
|
},
|
||||||
|
"label": "Version",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "datastoreconfig",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 1000,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "Datastore Config",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"children": [],
|
||||||
|
"validationRules": [],
|
||||||
|
"nodeId": 2,
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "users_on_this_instance",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {...record};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "reference",
|
||||||
|
"getShardName": "",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [],
|
||||||
|
"nodeId": 15
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"allidsShardFactor": 1,
|
||||||
|
"collectionName": "instances",
|
||||||
|
"isSingle": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "version",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 200,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "Name",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "package",
|
||||||
|
"type": "file",
|
||||||
|
"typeOptions": {},
|
||||||
|
"label": "Package",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"children": [],
|
||||||
|
"validationRules": [],
|
||||||
|
"nodeId": 3,
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "instances_for_this_version",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {name:record.name};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "ancestor",
|
||||||
|
"getShardName": "",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [],
|
||||||
|
"nodeId": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "instances_on_this_version",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {...record};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "reference",
|
||||||
|
"getShardName": "",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [],
|
||||||
|
"nodeId": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"allidsShardFactor": 1,
|
||||||
|
"collectionName": "versions",
|
||||||
|
"isSingle": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "session",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "created",
|
||||||
|
"type": "number",
|
||||||
|
"typeOptions": {
|
||||||
|
"minValue": 0,
|
||||||
|
"maxValue": 99999999999999,
|
||||||
|
"decimalPlaces": 0
|
||||||
|
},
|
||||||
|
"label": "Created",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_json",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": null,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "User Json",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "instanceDatastoreConfig",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": null,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "Instance Datastore Config",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": null,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "User",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"children": [],
|
||||||
|
"validationRules": [],
|
||||||
|
"nodeId": 16,
|
||||||
|
"indexes": [],
|
||||||
|
"allidsShardFactor": 1,
|
||||||
|
"collectionName": "sessions",
|
||||||
|
"isSingle": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"validationRules": [],
|
||||||
|
"nodeId": 1,
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "allinstances",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {...record};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "ancestor",
|
||||||
|
"getShardName": "",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"nodeId": 23
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sessions_by_user",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {username:record.username};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "ancestor",
|
||||||
|
"getShardName": "return record.username.substring(0,2)",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [
|
||||||
|
16
|
||||||
|
],
|
||||||
|
"nodeId": 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "user_name_lookup",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {name:record.unique_name, instanceDatastoreConfig:instance.datastoreconfig};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "ancestor",
|
||||||
|
"getShardName": "return record.unique_name.substring(0,2)",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"nodeId": 25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "all_versions",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {...record};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "ancestor",
|
||||||
|
"getShardName": "",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"nodeId": 26
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"allidsShardFactor": 64,
|
||||||
|
"collectionName": "applications",
|
||||||
|
"isSingle": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mastersession",
|
||||||
|
"type": "record",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "user_json",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": 10000,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "User Json",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"type": "string",
|
||||||
|
"typeOptions": {
|
||||||
|
"maxLength": null,
|
||||||
|
"values": null,
|
||||||
|
"allowDeclaredValuesOnly": false
|
||||||
|
},
|
||||||
|
"label": "User",
|
||||||
|
"getInitialValue": "default",
|
||||||
|
"getUndefinedValue": "default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"children": [],
|
||||||
|
"validationRules": [],
|
||||||
|
"nodeId": 17,
|
||||||
|
"indexes": [],
|
||||||
|
"allidsShardFactor": 64,
|
||||||
|
"collectionName": "sessions",
|
||||||
|
"isSingle": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pathMaps": [],
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "all_applications",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {...record};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "ancestor",
|
||||||
|
"getShardName": "",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"nodeId": 22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mastersessions_by_user",
|
||||||
|
"type": "index",
|
||||||
|
"map": "return {username:record.username};",
|
||||||
|
"filter": "",
|
||||||
|
"indexType": "ancestor",
|
||||||
|
"getShardName": "return record.username.substring(0,2)",
|
||||||
|
"getSortKey": "record.id",
|
||||||
|
"aggregateGroups": [],
|
||||||
|
"allowedRecordNodeIds": [
|
||||||
|
17
|
||||||
|
],
|
||||||
|
"nodeId": 27
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodeId": 0
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"output_to_file": {
|
||||||
|
"name": "output_to_file",
|
||||||
|
"behaviourSource": "main",
|
||||||
|
"behaviourName": "outputToFile",
|
||||||
|
"initialOptions": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"triggers": [
|
||||||
|
{
|
||||||
|
"actionName": "output_to_file",
|
||||||
|
"eventName": "authApi:createUser:onComplete",
|
||||||
|
"optionsCreator": "return { filename:'tempaccess' + context.user.name, content:context.result.tempCode };",
|
||||||
|
"condition": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
module.exports = (config) => ({
|
||||||
|
main: {
|
||||||
|
outputToFile : ({filename, content}) => {
|
||||||
|
fs.writeFile(`./tests/.data/${filename}`, content, {encoding:"utf8"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
File diff suppressed because one or more lines are too long
|
@ -6,6 +6,7 @@ const masterAppDefinition = constructHierarchy(
|
||||||
require("../appPackages/master/appDefinition.json"));
|
require("../appPackages/master/appDefinition.json"));
|
||||||
const {getApisWithFullAccess} = require("../utilities/budibaseApi");
|
const {getApisWithFullAccess} = require("../utilities/budibaseApi");
|
||||||
const { createTarGzPackage } = require("../utilities/targzAppPackage");
|
const { createTarGzPackage } = require("../utilities/targzAppPackage");
|
||||||
|
const { timeout } = require("./helpers");
|
||||||
|
|
||||||
module.exports = (app) => {
|
module.exports = (app) => {
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ module.exports = (app) => {
|
||||||
const version1 = master.recordApi
|
const version1 = master.recordApi
|
||||||
.getNew(`${newAppKey}/versions`, "version");
|
.getNew(`${newAppKey}/versions`, "version");
|
||||||
version1.name = "v1";
|
version1.name = "v1";
|
||||||
|
version1.defaultAccessLevel = "owner";
|
||||||
version1Key = version1.key;
|
version1Key = version1.key;
|
||||||
|
|
||||||
const { path, size } = await createTarGzPackage(app.config, "testApp");
|
const { path, size } = await createTarGzPackage(app.config, "testApp");
|
||||||
|
@ -57,26 +59,62 @@ module.exports = (app) => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let instance1Key;
|
let instance1;
|
||||||
it("should be able to create new instance of app", async () => {
|
it("should be able to create new instance of app", async () => {
|
||||||
const master = await getmaster();
|
const master = await getmaster();
|
||||||
const instance1 = master.recordApi
|
instance1 = master.recordApi
|
||||||
.getNew(`${newAppKey}/instances`, "instance");
|
.getNew(`${newAppKey}/instances`, "instance");
|
||||||
instance1.name = "instance 1";
|
instance1.name = "instance 1";
|
||||||
instance1.active = true;
|
instance1.active = true;
|
||||||
instance1.version = {key:version1Key, name:"v1", defaultAccessLevel:"owner"};
|
instance1.version = {key:version1Key, name:"v1", defaultAccessLevel:"owner"};
|
||||||
instance1Key = instance1.key;
|
|
||||||
|
|
||||||
await app.post(`/_master/api/record/${instance1.key}`, instance1)
|
await app.post(`/_master/api/record/${instance1.key}`, instance1)
|
||||||
.set("cookie", app.masterAuth.cookie)
|
.set("cookie", app.masterAuth.cookie)
|
||||||
.expect(statusCodes.OK);
|
.expect(statusCodes.OK);
|
||||||
|
|
||||||
|
const loadInstanceResponse = await app.get(`/_master/api/record/${instance1.key}`)
|
||||||
|
.set("cookie", app.masterAuth.cookie)
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
|
||||||
|
instance1 = loadInstanceResponse.body;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be able to create new user on instance", async () => {
|
let user1_instance1;
|
||||||
|
it("should be able to create new user on instance, via master", async () => {
|
||||||
|
const master = await getmaster();
|
||||||
|
user1_instance1 = master.recordApi
|
||||||
|
.getNew(`${newAppKey}/users`, "user");
|
||||||
|
user1_instance1.name = "testAppUser1";
|
||||||
|
|
||||||
|
|
||||||
|
/*const lookupResponse = await app.get(`/_master/api/lookup_field/${user1_instance1.key}?fields=instance`)
|
||||||
|
.set("cookie", app.masterAuth.cookie)
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
*/
|
||||||
|
user1_instance1.instance = instance1;
|
||||||
|
user1_instance1.active = true;
|
||||||
|
//await timeout(100);
|
||||||
|
await app.post(`/_master/api/record/${user1_instance1.key}`, user1_instance1)
|
||||||
|
.set("cookie", app.masterAuth.cookie)
|
||||||
|
.expect(statusCodes.OK);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should be able to set password for new user using temporary code", async () => {
|
||||||
|
const testUserTempCode = await readFile(`./tests/.data/tempaccess${user1_instance1.name}`, "utf8");
|
||||||
|
user1_instance1.password = "user1_instance1_password";
|
||||||
|
|
||||||
|
await app.post("/testApp/api/setPasswordFromTemporaryCode", {
|
||||||
|
username: user1_instance1.name,
|
||||||
|
tempCode:testUserTempCode,
|
||||||
|
newPassword:user1_instance1.password
|
||||||
|
})
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
|
||||||
|
await app.post("/testApp/api/authenticate", {
|
||||||
|
username: user1_instance1.name,
|
||||||
|
password: user1_instance1.password
|
||||||
|
})
|
||||||
|
.expect(statusCodes.OK);
|
||||||
|
})
|
||||||
}
|
}
|
|
@ -1,14 +1,24 @@
|
||||||
const { join } = require("path");
|
const { join } = require("path");
|
||||||
const constructHierarchy = require("./constructHierarchy");
|
const constructHierarchy = require("./constructHierarchy");
|
||||||
const { common } = require("budibase-core");
|
const { common } = require("budibase-core");
|
||||||
const createAppPackage = (appPath) => ({
|
const { getRuntimePackageDirectory } = require("../utilities/runtimePackages");
|
||||||
appDefinition: require(join(appPath, "appDefinition.json")),
|
const createAppPackage = (config, appPath) => {
|
||||||
behaviourSources: require(join(appPath, "plugins.js")),
|
|
||||||
appPath
|
const appDefModule = require(
|
||||||
});
|
join(appPath, "appDefinition.json"));
|
||||||
|
|
||||||
|
const pluginsModule = require(
|
||||||
|
join(appPath, "plugins.js"));
|
||||||
|
|
||||||
|
return ({
|
||||||
|
appDefinition: appDefModule,
|
||||||
|
behaviourSources: pluginsModule(config),
|
||||||
|
appPath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.masterAppPackage = (config) => {
|
module.exports.masterAppPackage = (config) => {
|
||||||
const standardPackage = createAppPackage("../appPackages/master");
|
const standardPackage = createAppPackage(config, "../appPackages/master");
|
||||||
|
|
||||||
const customizeMaster = config && config.customizeMaster
|
const customizeMaster = config && config.customizeMaster
|
||||||
? config.customizeMaster
|
? config.customizeMaster
|
||||||
|
@ -31,8 +41,11 @@ module.exports.masterAppPackage = (config) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.applictionVersionPackage = (appname, versionId) => {
|
module.exports.applictionVersionPackage = (config, appname, versionId) => {
|
||||||
const pkg = createAppPackage(`../runtimePackages/${appname}/${versionId}`);
|
const pkg = createAppPackage(
|
||||||
pkg.appDefinition = constructHierarchy(appDefinition);
|
config,
|
||||||
|
join("..", getRuntimePackageDirectory(appname, versionId))
|
||||||
|
);
|
||||||
|
pkg.appDefinition = constructHierarchy(pkg.appDefinition);
|
||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,22 +88,20 @@ module.exports = async (config) => {
|
||||||
|
|
||||||
const app = await getApplication(appname);
|
const app = await getApplication(appname);
|
||||||
|
|
||||||
const userInMaster = await bb.indexApi.listItems(
|
const userInMaster = await getUser(bb, app.id, username);
|
||||||
`/applications/${app.id}/users_by_name`,
|
|
||||||
{name:username}
|
|
||||||
).find(u => u.name === username);
|
|
||||||
|
|
||||||
const instance = await bb.recordApi.load(
|
const instance = await bb.recordApi.load(
|
||||||
userInMaster.instance.key);
|
userInMaster.instanceKey);
|
||||||
|
|
||||||
const versionId = $(instance.version.key, [
|
const versionId = $(instance.version.key, [
|
||||||
splitKey,
|
splitKey,
|
||||||
last
|
last
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const dsConfig = JSON.parse(instance.datastoreconfig);
|
||||||
const bbInstance = await getApisWithFullAccess(
|
const bbInstance = await getApisWithFullAccess(
|
||||||
datastoreModule.getDatastore(instance.datastoreconfig),
|
datastoreModule.getDatastore(dsConfig),
|
||||||
applictionVersionPackage(appname, versionId)
|
applictionVersionPackage(config, appname, versionId)
|
||||||
);
|
);
|
||||||
|
|
||||||
const authUser = await bbInstance.authApi.authenticate(username, password);
|
const authUser = await bbInstance.authApi.authenticate(username, password);
|
||||||
|
@ -140,10 +138,11 @@ module.exports = async (config) => {
|
||||||
const customId = bb.recordApi.customId("session", sessionId);
|
const customId = bb.recordApi.customId("session", sessionId);
|
||||||
try {
|
try {
|
||||||
const session = await bb.recordApi.load(`/applications/${app.id}/sessions/${customId}`);
|
const session = await bb.recordApi.load(`/applications/${app.id}/sessions/${customId}`);
|
||||||
const instanceDatastore = getInstanceDatastore(session.instanceDatastoreConfig)
|
const dsConfig = JSON.parse(session.instanceDatastoreConfig);
|
||||||
|
const instanceDatastore = getInstanceDatastore(dsConfig)
|
||||||
return await getApisForSession(
|
return await getApisForSession(
|
||||||
instanceDatastore,
|
instanceDatastore,
|
||||||
applictionVersionPackage(appname, session.instanceVersion),
|
applictionVersionPackage(config, appname, session.instanceVersion),
|
||||||
session);
|
session);
|
||||||
} catch(_) {
|
} catch(_) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -151,6 +150,19 @@ module.exports = async (config) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getUser = async (bb, appId, username ) => {
|
||||||
|
const matches = await bb.indexApi.listItems(
|
||||||
|
`/applications/${appId}/user_name_lookup`,
|
||||||
|
{
|
||||||
|
rangeStartParams:{name:username},
|
||||||
|
rangeEndParams:{name:username},
|
||||||
|
searchPhrase:`name:${username}`
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if(matches.length !== 1) return;
|
||||||
|
return matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
const getFullAccessInstanceApiForUsername = async (appname, username) => {
|
const getFullAccessInstanceApiForUsername = async (appname, username) => {
|
||||||
|
|
||||||
if(isMaster(appname)) {
|
if(isMaster(appname)) {
|
||||||
|
@ -158,20 +170,21 @@ module.exports = async (config) => {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const app = await getApplication(appname);
|
const app = await getApplication(appname);
|
||||||
const matches = bb.indexApi.listItems(
|
const user = await getUser(bb, app.id, username);
|
||||||
`/applications/${app.id}/user_name_lookup`,
|
|
||||||
{
|
|
||||||
rangeStartParams:{name:username},
|
|
||||||
rangeEndParams:{name:username},
|
|
||||||
searchPhrase:`name:${username}`
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if(matches.length !== 1) return;
|
|
||||||
|
|
||||||
|
const dsConfig = JSON.parse(user.instanceDatastoreConfig);
|
||||||
const instanceDatastore = getInstanceDatastore(
|
const instanceDatastore = getInstanceDatastore(
|
||||||
matches[0].instanceDatastoreConfig);
|
dsConfig
|
||||||
|
);
|
||||||
|
|
||||||
return await getApisWithFullAccess(instanceDatastore);
|
const versionId = $((await bb.recordApi.load(user.instanceKey)).version.key, [
|
||||||
|
splitKey,
|
||||||
|
last
|
||||||
|
]);
|
||||||
|
|
||||||
|
return await getApisWithFullAccess(
|
||||||
|
instanceDatastore,
|
||||||
|
applictionVersionPackage(config, appname, versionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue