Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@looker/embed-sdk

Package Overview
Dependencies
Maintainers
3
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@looker/embed-sdk - npm Package Compare versions

Comparing version 1.0.0-beta.1 to 1.0.0-beta.2

demo/demo.py

3

config.js
require('dotenv').config();
module.exports = {
host: process.env.LOOKER_EMBED_HOST || 'localhost:9999',
domain: process.env.LOOKER_EMBED_DOMAIN || 'localhost:8080',
host: process.env.LOOKER_EMBED_HOST || 'self-signed.looker.com:9999',
secret: process.env.LOOKER_EMBED_SECRET || 'ranger2'
}

@@ -18,4 +18,3 @@ {

"models": ["powered_by", "thelook"],
"user_attributes": { "locale": "en_US" },
"access_filters": { "powered_by": { "products.brand": "Allegra K" } }
"user_attributes": { "locale": "en_US" }
}

@@ -19,2 +19,3 @@ // Karma configuration

{pattern: 'src/**/*.ts'},
{pattern: 'server_utils/**/*.ts'},
{pattern: 'tests/**/*.spec.ts'},

@@ -21,0 +22,0 @@ {pattern: 'tests/**/*.html'}

{
"name": "@looker/embed-sdk",
"version": "1.0.0-beta.1",
"version": "1.0.0-beta.2",
"description": "A toolkit for embedding Looker",

@@ -17,6 +17,7 @@ "main": "dist/main.js",

"build_utils": "tsc --build tsconfig-server.json",
"clean": "rm -r lib dist",
"lint": "tslint --project tsconfig.json --format stylish 'src/**/*.ts' 'server_utils/*.ts'",
"lint-fix": "tslint --fix --project tsconfig.json --format stylish 'src/**/*.ts' 'server_utils/*.ts'",
"clean": "rm -rf lib dist",
"lint": "tslint --project tsconfig-lint.json --format stylish",
"lint-fix": "tslint --fix --project tsconfig-lint.json --format stylish",
"start": "npm run build_utils && webpack-dev-server --config webpack-devserver.config.js --hot --inline --open --color --progress",
"python": "webpack --config webpack-devserver.config.js && python demo/demo.py",
"test": "npm run lint && karma start karma.conf.js",

@@ -37,5 +38,7 @@ "test-once": "npm run lint && karma start karma.conf.js --single-run "

"@babel/core": "^7.3.3",
"@types/create-hmac": "^1.1.0",
"@types/jasmine": "^2.8.2",
"@types/node": "^11.12.1",
"babel-loader": "^8.0.5",
"create-hmac": "^1.1.7",
"dotenv": "^6.2.0",

@@ -52,2 +55,3 @@ "jasmine-core": "^2.8.0",

"tslint-config-standard": "^8.0.0",
"tslint-defocus": "^2.0.6",
"tslint-eslint-rules": "^4.1.1",

@@ -54,0 +58,0 @@ "typescript": "^3.3.3",

@@ -187,2 +187,7 @@ # Looker JavaScript Embed SDK

* Create a file named `.env` in the root of the sdk directory. Add a line to that file: `LOOKER_EMBED_SECRET="YourLookerSecret"`
* Provide your Looker instance host address to the server by either:
* Setting it as `LOOKER_EMBED_HOST` in your shell environment.
* Adding `LOOKER_EMBED_HOST="yourinstance.looker.com:yourport"` to the `.env` file.
* Edit the `demo/demo_config.ts` file to be appropriate for the pages you want to embed.

@@ -255,4 +260,14 @@

#### Node server
* `npm install`
* `npm start`
* The server will print out what host and port it is running on. If it is different than `http://localhost:8080` then you will need to add that to your Embedded Domain Whitelist.
#### Python server
* `npm install`
* `npm run python`
* The server will print out what host and port it is running on.
You may need to `pip install six` to install the Python 2/3 compatibility layer.

@@ -26,7 +26,10 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var crypto_1 = require("crypto");
var createHmac = require("create-hmac");
function stringify(params) {
var result = [];
for (var key in params) {
result.push(key + "=" + encodeURIComponent(params[key]));
var param = params[key];
if (typeof param === 'string') {
result.push(key + "=" + encodeURIComponent(param));
}
}

@@ -39,3 +42,3 @@ return result.join('&');

function signEmbedUrl(data, secret) {
var stringToSign = [
var stringsToSign = [
data.host,

@@ -48,11 +51,15 @@ data.embed_path,

data.permissions,
data.models,
data.group_ids,
data.external_group_id,
data.user_attributes,
data.access_filters
].join('\n');
return crypto_1.createHmac('sha1', secret).update(forceUnicodeEncoding(stringToSign)).digest('base64').trim();
data.models
];
if (data.group_ids)
stringsToSign.push(data.group_ids);
if (data.external_group_id)
stringsToSign.push(data.external_group_id);
if (data.user_attributes)
stringsToSign.push(data.user_attributes);
stringsToSign.push(data.access_filters);
var stringToSign = stringsToSign.join('\n');
return createHmac('sha1', secret).update(forceUnicodeEncoding(stringToSign)).digest('base64').trim();
}
function nonce(len) {
function createNonce(len) {
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

@@ -65,5 +72,6 @@ var text = '';

}
function createSignedUrl(src, user, host, secret) {
;
function createSignedUrl(src, user, host, secret, nonce) {
var jsonTime = JSON.stringify(Math.floor((new Date()).getTime() / 1000));
var jsonNonce = JSON.stringify(nonce(16));
var jsonNonce = JSON.stringify(nonce || createNonce(16));
var params = {

@@ -75,6 +83,7 @@ external_user_id: JSON.stringify(user.external_user_id),

models: JSON.stringify(user.models),
group_ids: JSON.stringify(user.group_ids || []),
group_ids: JSON.stringify(user.group_ids),
user_attributes: JSON.stringify(user.user_attributes),
external_group_id: JSON.stringify(user.external_group_id),
access_filters: JSON.stringify(user.access_filters),
access_filters: JSON.stringify(user.access_filters || {}),
user_timezone: JSON.stringify(user.user_timezone),
force_logout_login: JSON.stringify(user.force_logout_login),

@@ -81,0 +90,0 @@ session_length: JSON.stringify(user.session_length),

@@ -25,8 +25,11 @@ /*

import { createHmac } from 'crypto'
import * as createHmac from 'create-hmac'
function stringify (params: {[key: string]: string}) {
function stringify (params: {[key: string]: string | undefined}) {
const result = []
for (const key in params) {
result.push(`${key}=${encodeURIComponent(params[key])}`)
const param = params[key]
if (typeof param === 'string') {
result.push(`${key}=${encodeURIComponent(param)}`)
}
}

@@ -41,3 +44,3 @@ return result.join('&')

function signEmbedUrl (data: {[key: string]: string}, secret: string) {
const stringToSign = [
const stringsToSign = [
data.host,

@@ -51,12 +54,14 @@ data.embed_path,

data.permissions,
data.models,
data.group_ids,
data.external_group_id,
data.user_attributes,
data.access_filters
].join('\n')
data.models
]
if (data.group_ids) stringsToSign.push(data.group_ids)
if (data.external_group_id) stringsToSign.push(data.external_group_id)
if (data.user_attributes) stringsToSign.push(data.user_attributes)
stringsToSign.push(data.access_filters)
const stringToSign = stringsToSign.join('\n')
return createHmac('sha1', secret).update(forceUnicodeEncoding(stringToSign)).digest('base64').trim()
}
function nonce (len: number) {
function createNonce (len: number) {
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'

@@ -96,3 +101,3 @@ let text = ''

session_length: number
force_logout_login?: boolean,
force_logout_login: boolean,
permissions: LookerUserPermission[]

@@ -103,8 +108,15 @@ models: string[]

user_attributes?: {[key: string]: any}
access_filters: {[key: string]: any}
user_timezone?: string | null
access_filters?: {[key: string]: any}
}
export function createSignedUrl (src: string, user: LookerEmbedUser, host: string, secret: string) {
export function createSignedUrl (
src: string,
user: LookerEmbedUser,
host: string,
secret: string,
nonce?: string
) {
const jsonTime = JSON.stringify(Math.floor((new Date()).getTime() / 1000))
const jsonNonce = JSON.stringify(nonce(16))
const jsonNonce = JSON.stringify(nonce || createNonce(16))
const params = {

@@ -116,6 +128,7 @@ external_user_id: JSON.stringify(user.external_user_id),

models: JSON.stringify(user.models),
group_ids: JSON.stringify(user.group_ids || []),
group_ids: JSON.stringify(user.group_ids),
user_attributes: JSON.stringify(user.user_attributes),
external_group_id: JSON.stringify(user.external_group_id),
access_filters: JSON.stringify(user.access_filters),
access_filters: JSON.stringify(user.access_filters || {}),
user_timezone: JSON.stringify(user.user_timezone),

@@ -122,0 +135,0 @@ force_logout_login: JSON.stringify(user.force_logout_login),

@@ -27,2 +27,3 @@ /*

import { EmbedClient } from '../src/embed'
import { EmbedBuilder } from '../src/embed_builder'
import { LookerEmbedExplore } from '../src/explore_client'

@@ -33,4 +34,4 @@ import { LookerEmbedSDK } from '../src/index'

describe('LookerEmbedBuilder', () => {
let builder
let el
let builder: EmbedBuilder<LookerEmbedDashboard>
let el: HTMLDivElement

@@ -149,7 +150,31 @@ beforeEach(() => {

it('should add a second on<action> handler', () => {
const dance = jasmine.createSpy('dance')
const pizza = jasmine.createSpy('pizza')
builder.on('party', dance)
builder.on('party', pizza)
expect(builder.handlers.party).toEqual([dance, pizza])
})
it('should add url parameters', () => {
builder.withParams({ alpha: 1, beta: 2 })
builder.withParams({ alpha: '1', beta: '2' })
expect(builder.embedUrl).toMatch('alpha=1&beta=2')
})
it('should allow specifying a theme', () => {
builder.withTheme('Fancy')
expect(builder.embedUrl).toMatch('theme=Fancy')
})
it('should allow specifying filters for dashboards', () => {
builder.withFilters({ 'State / Region': 'California' })
expect(builder.embedUrl).toMatch('State%20%2F%20Region=California')
})
it('should allow specifying filters for looks', () => {
builder = LookerEmbedSDK.createLookWithId(1)
builder.withFilters({ 'State / Region': 'California' })
expect(builder.embedUrl).toMatch('f%5BState%20%2F%20Region%5D=California')
})
it('should allow adding sandbox attributes', () => {

@@ -156,0 +181,0 @@ builder.withSandboxAttr('alpha')

@@ -28,2 +28,3 @@ /*

import mock from 'xhr-mock'
import { EmbedClient } from '../src/embed'

@@ -35,3 +36,3 @@ const testUrl = '/base/tests/test.html'

let el
let client
let client: any

@@ -45,3 +46,3 @@ beforeEach(() => {

describe('with ID', () => {
let fakeDashboardClient
let fakeDashboardClient: any

@@ -69,3 +70,3 @@ beforeEach(() => {

})
.catch(expect(false))
.catch(done.fail)
})

@@ -80,3 +81,3 @@

.then(() => false)
.catch(expect(false))
.catch(done.fail)

@@ -88,8 +89,23 @@ client.connect()

})
.catch(expect(false))
.catch(done.fail)
})
it('should handle failures', (done) => {
mock.reset()
mock.get(/\/auth\?src=/, (req, res) => {
expect(req.header('Cache-Control')).toEqual('no-cache')
return res.status(403).statusText('foo')
})
client.connect()
.then(done.fail)
.catch((error: any) => {
expect(error).toEqual('foo')
done()
})
})
})
describe('with URL', () => {
let fakeDashboardClient
let fakeDashboardClient: any

@@ -114,3 +130,3 @@ beforeEach(() => {

})
.catch(expect(false))
.catch(done.fail)
})

@@ -121,3 +137,3 @@

.then(() => false)
.catch(expect(false))
.catch(done.fail)

@@ -129,3 +145,3 @@ client.connect()

})
.catch(expect(false))
.catch(done.fail)
})

@@ -136,4 +152,4 @@ })

let fakeDashboardClient
let el
let iframe
let el: HTMLDivElement
let iframe: HTMLIFrameElement

@@ -153,3 +169,3 @@ beforeEach(() => {

spyOn(window, 'fetch')
spyOn(ChattyHost.prototype, 'connect').and.callFake(async function () {
spyOn(ChattyHost.prototype, 'connect').and.callFake(async function (this: any) {
iframe = this.iframe

@@ -169,2 +185,3 @@ return Promise.resolve({})

expect(iframe.classList.toString()).toEqual('classy')
// tslint:disable-next-line:deprecation
expect(iframe.frameBorder).toEqual('0')

@@ -174,5 +191,5 @@ expect(iframe.src).toMatch(testUrl)

})
.catch(expect(false))
.catch(done.fail)
})
})
})
{
"defaultSeverity": "error",
"extends": [
"tslint-defocus",
"tslint-config-standard"

@@ -8,2 +9,3 @@ ],

"rules": {
"defocus": true,
"no-namespace": [true, "allow-declarations"],

@@ -10,0 +12,0 @@ "prefer-const": [true, {"destructuring": "all"}],

@@ -13,3 +13,3 @@ var path = require('path')

filename: "[name].js",
path: path.join(__dirname, "demo", "build")
path: path.join(__dirname, "demo")
},

@@ -26,3 +26,8 @@ resolve: {

test: /\.ts$/,
loader: "ts-loader"
loader: "ts-loader",
options: {
compilerOptions: {
declaration: false
}
}
}

@@ -34,4 +39,3 @@ ]

contentBase: [
path.join(__dirname, "demo"),
path.join(__dirname, "demo", "build")
path.join(__dirname, "demo")
],

@@ -38,0 +42,0 @@ watchContentBase: true,

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc