Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"azureFunctions.deploySubpath": "api",
"azureFunctions.postDeployTask": "npm install",
"azureFunctions.projectLanguage": "JavaScript",
"azureFunctions.projectRuntime": "~3",
"debug.internalConsoleOptions": "neverOpen",
"azureFunctions.preDeployTask": "npm prune"
}
{
"azureFunctions.deploySubpath": "api",
"azureFunctions.postDeployTask": "npm install",
"azureFunctions.projectLanguage": "JavaScript",
"azureFunctions.projectRuntime": "~3",
"debug.internalConsoleOptions": "neverOpen",
"azureFunctions.preDeployTask": "npm prune",
"azureFunctions.projectSubpath": "api"
}
8 changes: 5 additions & 3 deletions DEPLOY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@

1. Run `npm install` from the VS Code Terminal to install the [node-fetch](https://www.npmjs.com/package/node-fetch) dependency.

1. From the Azure Functions extension within VS Code, click **Deploy to Function App** (cloud icon) and select or create a Function App in Azure.
1. From the Azure Functions extension within VS Code, click **Deploy to Function App** (cloud icon) and select a Function App in Azure. If needed, you can first create a new Azure Function resource within the Azure Portal before deploying from VS Code.

1. From the Azure Function in Azure Portal, click **Configuration** to add the following application settings using either the names & values previously pasted into `/api/local.settings.json` or new values for production resources.
1. From the Azure Function in Azure Portal, click **Configuration** to add the following application settings using either the names & values previously pasted into `/api/local.settings.json` or new values for production resources. Click **Save** to update your Function App.
- AadTenantId
- AppClientId
- AppClientSecret

1. Copy the Function URL from VS Code or Azure Portal (including a key that adds code param) and open in a browser to confirm a successful response from the AAD Token API. If needed, you can troubleshoot issues in the Portal by browsing to the **Functions** and **Code + Test** to debug logs while making an HTTP request.
1. Copy the Function URL from VS Code or Azure Portal (including a key that adds code param) and open in a browser to confirm a successful response from the AAD Token API. If needed, you can troubleshoot issues in the Portal by browsing to the **Functions** then **AadToken** for the **Function Keys** as well as **Code + Test** to debug logs while making an HTTP request.

1. When a token is successfully returned from the API, override the `fetchToken()` reference to `apiUrl` within [src/App/helper.js](./src/App/helper.js#L26) using your new Function URL. It will be in this format: `https://APPNAME.azurewebsites.net/api/aad/token?code=DEFAULT_KEY`

Expand Down Expand Up @@ -62,3 +62,5 @@
1. Copy the Static Web App URL from the **Overview** page, then go back to the Azure Function and click **CORS** to paste your app URL in the Allowed Origins.

1. Open the Static Web App URL to confirm it is working the same as the [local deployment method](./README.md).

1. See [Troubleshooting](./TROUBLESHOOTING.md) doc for more help or [file a new issue](https://github.com/microsoft/Purview-Custom-Types-Tool-Solution-Accelerator/issues).
10 changes: 10 additions & 0 deletions TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Troubleshooting

## Debug Azure Deployments

1. If possible, [run the app locally](https://github.com/microsoft/Purview-Custom-Types-Tool-Solution-Accelerator#local-setup) to confirm your configuration values are correct and your application service principal has the permission to access your Purview account.

1. Ensure your deployed Function returns a valid token via JSON:
```https://{AzFuncName}.azurewebsites.net/api/aad/token?code={AzFuncKey}```

1. Use the web browser's `More Tools > Developer Tools > Console` (Ctrl + Shift + I) to debug the API calls and responses.
4 changes: 3 additions & 1 deletion api/Purview/purviewHelper.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
const fetch = require("node-fetch");
// const fetch = require("node-fetch");

const AtlasAccountName = process.env["AtlasAccountName"] || null,
apiPrefix = `https://${AtlasAccountName}.catalog.purview.azure.com/api`;

// GET all type definitions
async function getTypeDefs(token) {
const fetch = (await import('node-fetch')).default;

const apiUrl = (token && `${apiPrefix}/atlas/v2/types/typedefs`) || null,
fetchResponse = apiUrl && await fetch(apiUrl, {headers:{'Authorization': `Bearer ${token}`}});

Expand Down
12 changes: 7 additions & 5 deletions api/Storage/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ module.exports = async function (context, req) {
const STORAGE_CONNECTION_STRING = process.env["StorageConnectionString"] || null,
STORAGE_CONTAINER = process.env["StorageContainer"] || null,
blobServiceClient = STORAGE_CONNECTION_STRING
&& BlobServiceClient.fromConnectionString(STORAGE_CONNECTION_STRING) || null;

let contentBody = '';
let httpStatus = 400;
&& BlobServiceClient.fromConnectionString(STORAGE_CONNECTION_STRING) || null,
blobContainers = (blobServiceClient && await blobServiceClient.listContainers()) || null;

let contentBody = { version: "v1.1" },
httpStatus = 400;

context.log(`GET all containers looking for '${STORAGE_CONTAINER}'...`);
let containerExists = false;
for await (const container of blobServiceClient.listContainers()) {

for await (const container of blobContainers) {
const containerName = (container && container.name) || null;
if (containerName === STORAGE_CONTAINER) {
containerExists = true;
Expand Down
5 changes: 4 additions & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"start": "func start",
"test": "echo \"No tests yet...\""
},
"dependencies": {},
"dependencies": {
"@azure/storage-blob": "^12.11.0",
"node-fetch": "^3.2.3"
},
"devDependencies": {}
}
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Create custom type definitions in Microsoft Purview" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Purview Custom Types Tool</title>
</head>
<body>
Expand Down
15 changes: 0 additions & 15 deletions public/manifest.json

This file was deleted.

20 changes: 13 additions & 7 deletions src/App/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export async function fetchAuth(callback) {

if (contentType && contentType.indexOf("application/json") !== -1) {
await authResponse.json()
.then(authResponse => callback(authResponse))
.then(authResponse => {
console.log('### authResponse:', authResponse);
callback(authResponse);
})
.catch(error => console.error('Error:', error));
}
}
Expand All @@ -37,6 +40,8 @@ export async function fetchToken(callback) {
tokenResponseData = (tokenResponseStatus===200 && tokenResponse.data) || null,
tokenType = (tokenResponseData && tokenResponseData.token_type) || null;

console.log('### tokenResponse:', tokenResponse);

// Set token value
if (tokenType==='Bearer' && tokenResponseData.access_token) tokenAccess = tokenResponseData.access_token;
})
Expand All @@ -52,13 +57,13 @@ export async function fetchContainer(callback) {
console.log(`### FETCH: GET ${apiUrl}`);
const storageResponse = await fetch(apiUrl).catch(error => console.error('Error:', error)),
contentType = storageResponse && storageResponse.headers.get("content-type");

if (contentType && contentType.indexOf("application/json") !== -1) {
await storageResponse.json()
.then(storageResponse => {
const responseStatus = storageResponse && storageResponse.status,
responseData = storageResponse && storageResponse.data,
container = responseData && responseData.name;
container = responseData && (responseData.name || responseData._containerName);
if (responseStatus === 200 && container) {
callback(container);
console.log('### container:', container);
Expand Down Expand Up @@ -87,10 +92,11 @@ export async function handleApiTypes(response, callback) {
if (contentType && contentType.indexOf("application/json") !== -1) {
await response.json()
.then(response => {
const responseStatus = response && response.status;
if (responseStatus === 200) {
callback(response.data);
console.log('### typeDefsObj:', response.data);
const responseStatus = (response && response.status) || null,
responseData = (response && response.data) || null;
console.log('### typeDefsObj:', responseData);
if (responseStatus === 200 && responseData) {
callback(responseData);
}
})
.catch(error => console.error('Error:', error));
Expand Down
10 changes: 6 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import App from './App/App';

ReactDOM.render(
const container = document.getElementById('root');
const root = createRoot(container); // createRoot(container!) if you use TypeScript

root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
</React.StrictMode>
);
36 changes: 36 additions & 0 deletions staticwebapp.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"trailingSlash": "auto",

"routes": [
{ "route": "/logout", "rewrite": "/.auth/logout" },
{ "route": "/login", "rewrite": "/.auth/login/aad" },
{ "route": "/.auth/login/github", "statusCode": 404 },
{ "route": "/.auth/login/google", "statusCode": 404 },
{ "route": "/.auth/login/facebook", "statusCode": 404 },
{ "route": "/.auth/login/twitter", "statusCode": 404 },
{
"route": "/*",
"allowedRoles": ["admin"]
}
],

"responseOverrides": {
"401": {
"statusCode": 302,
"redirect": "/login"
}
},

"navigationFallback": {
"rewrite": "/index.html",
"exclude": ["/assets/*", "/*.{json,txt}"]
},

"mimeTypes": {
".json": "text/json"
},

"platform": {
"apiRuntime": "node:14"
}
}