Video.js with markers in a React TypeScript


 

To implement Video.js with markers in a React TypeScript project, you can follow these steps:


1. **Install Dependencies:**


   Make sure you have the necessary packages installed. Install `video.js` and `videojs-markers` using npm:


   ```bash

   npm install video.js videojs-markers

   ```


2. **Import Dependencies:**


   In your React component file, import the required dependencies:


import videojs from 'video.js';

import 'video.js/dist/video-js.css';

import 'videojs-markers/dist/videojs.markers.css';

import 'videojs-markers';


3. **Create the Video Player Component:**


   Create a React component for your video player. You can use the `useEffect` hook to initialize the video player and markers:


import React, { useEffect, useRef } from 'react';



const VideoPlayer: React.FC = () => {

const videoRef = useRef<HTMLVideoElement>(null);



useEffect(() => {

// Initialize video player

const player = videojs(videoRef.current, {}, () => {

console.log('Video.js player is ready');

});



// Add markers

const markers = [

{ time: 10, text: 'Marker 1' },

{ time: 20, text: 'Marker 2' },

// Add more markers as needed

];



player.markers({

markers,

});



// Cleanup on component unmount

return () => {

player.dispose(); // Dispose of the video player instance

};

}, []); // Run only on component mount



return (

<div data-vjs-player>

<video ref={videoRef} className="video-js vjs-default-skin" controls>

<source src="your-video-source.mp4" type="video/mp4" />

</video>

</div>

);

};



export default VideoPlayer;


   Make sure to replace `"your-video-source.mp4"` with the actual source URL of your video.


4. **Styling:**


   You may want to add some styling to your component. You can customize the appearance using CSS.


.video-js {

width: 100%;

height: auto;

}

5. **Usage:**


   Use your `VideoPlayer` component wherever you need it in your application:


import React from 'react';

import VideoPlayer from './VideoPlayer';



const App: React.FC = () => {

return (

<div>

<h1>Your React Video Player</h1>

<VideoPlayer />

</div>

);

};



export default App;


Ensure you have the correct paths and URLs for your video source, and adjust the markers array as needed. This example assumes you have a single video source, but you can customize it for multiple sources or other configurations based on your requirements.

0 comments:

Video JS with marker for react typescript

Video Player



export const videoPlayer = ()=>{ var document:any = window.document; // Does the browser actually support the video element? var supportsVideo = !!document.createElement('video').canPlayType; if (supportsVideo) { // Obtain handles to main elements var videoContainer = document.getElementById('videoContainer'); var video = document.getElementById('video'); var videoControls = document.getElementById('video-controls'); videoContainer.oncontextmenu=function(){return false} // Hide the default controls video.controls = false; // Display the user defined video controls videoControls.style.display = 'block'; // Obtain handles to buttons and other elements var playpause:any = document.getElementById('playpause'); var stop:any = document.getElementById('stop'); var mute:any = document.getElementById('mute'); var volinc:any = document.getElementById('volinc'); var voldec:any = document.getElementById('voldec'); var progress:any = document.getElementById('progress'); var progressBar:any = document.getElementById('progress-bar'); var fullscreen:any = document.getElementById('fs'); // Check if the browser supports the Fullscreen API var fullScreenEnabled = !!(document.fullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled || document.webkitSupportsFullscreen || document.webkitFullscreenEnabled || document.createElement('video').webkitRequestFullScreen); // If the browser doesn't support the Fulscreen API then hide the fullscreen button if (!fullScreenEnabled) { fullscreen.style.display = 'none'; playpause.style.textIndent = "1px" playpause.style.color = "white" } var alterVolume = function(dir:any) { var currentVolume = Math.floor(video.volume * 10) / 10; if (dir === '+') { if (currentVolume < 1) video.volume += 0.1; } else if (dir === '-') { if (currentVolume > 0) video.volume -= 0.1; } } // Set the video container's fullscreen state var setFullscreenData = function(state:any) { videoContainer.setAttribute('data-fullscreen', !!state); } // Checks if the document is currently in fullscreen mode var isFullScreen = function() { return !!(document.fullScreen || document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement); } // Fullscreen var handleFullscreen = function() { // If fullscreen mode is active... if (isFullScreen()) { // ...exit fullscreen mode // (Note: this can only be called on document) if (document.exitFullscreen) document.exitFullscreen(); else if (document.mozCancelFullScreen) document.mozCancelFullScreen(); else if (document.webkitCancelFullScreen) document.webkitCancelFullScreen(); else if (document.msExitFullscreen) document.msExitFullscreen(); setFullscreenData(false); } else { // ...otherwise enter fullscreen mode // (Note: can be called on document, but here the specific element is used as it will also ensure that the element's children, e.g. the custom controls, go fullscreen also) if (videoContainer.requestFullscreen) videoContainer.requestFullscreen(); else if (videoContainer.mozRequestFullScreen) videoContainer.mozRequestFullScreen(); else if (videoContainer.webkitRequestFullScreen) { // Safari 5.1 only allows proper fullscreen on the video element. This also works fine on other WebKit browsers as the following CSS (set in styles.css) hides the default controls that appear again, and // ensures that our custom controls are visible: // figure[data-fullscreen=true] video::-webkit-media-controls { display:none !important; } // figure[data-fullscreen=true] .controls { z-index:2147483647; } video.webkitRequestFullScreen(); } else if (videoContainer.msRequestFullscreen) videoContainer.msRequestFullscreen(); setFullscreenData(true); } } // Only add the events if addEventListener is supported (IE8 and less don't support it, but that will use Flash anyway) if (document.addEventListener) { // Wait for the video's meta data to be loaded, then set the progress bar's max value to the duration of the video video.addEventListener('loadedmetadata', function() { progress.setAttribute('max', video.duration); }); // Add events for all buttons playpause.addEventListener('click', function(e:any) { if (video.paused || video.ended) video.play(); else video.pause(); }); // The Media API has no 'stop()' function, so pause the video and reset its time and the progress bar stop.addEventListener('click', function(e:any) { video.pause(); video.currentTime = 0; progress.value = 0; }); mute.addEventListener('click', function(e:any) { video.muted = !video.muted; }); volinc.addEventListener('click', function(e:any) { alterVolume('+'); }); voldec.addEventListener('click', function(e:any) { alterVolume('-'); }); fullscreen.addEventListener('click', function(e:any) { handleFullscreen(); }); // As the video is playing, update the progress bar video.addEventListener('timeupdate', function() { // For mobile browsers, ensure that the progress element's max attribute is set if (!progress.getAttribute('max')) progress.setAttribute('max', video.duration); progress.value = video.currentTime; progressBar.style.width = Math.floor((video.currentTime / video.duration) * 100) + '%'; }); // React to the user clicking within the progress bar progress.addEventListener('click', function(e:any) { try{ var rect = progress.getBoundingClientRect(); var pos = (e.pageX - rect.left) / rect.width; video.currentTime = pos * video.duration; } catch(e){ console.log(e) } }); // Listen for fullscreen change events (from other controls, e.g. right clicking on the video itself) document.addEventListener('fullscreenchange', function(e:any) { setFullscreenData(!!(document.fullScreen || document.fullscreenElement)); }); document.addEventListener('webkitfullscreenchange', function() { setFullscreenData(!!document.webkitIsFullScreen); }); document.addEventListener('mozfullscreenchange', function() { setFullscreenData(!!document.mozFullScreen); }); document.addEventListener('msfullscreenchange', function() { setFullscreenData(!!document.msFullscreenElement); }); } } }

vid-marker

import videojs, { VideoJsPlayer } from 'video.js'; const Plugin = videojs.getPlugin('plugin'); // default setting const defaultSetting: VideoJsMarkerPluginSettings = { markerStyle: { width: '7px', 'border-radius': '30%', 'background-color': 'red' }, markerTip: { display: true, text(marker) { return '' + marker.text; }, time(marker) { return marker.time; } }, breakOverlay: { display: false, displayTime: 3, text(marker) { return 'Break overlay: ' + marker.overlayText; }, style: { width: '100%', height: '20%', 'background-color': 'rgba(0,0,0,0.7)', color: 'white', 'font-size': '17px' } }, onMarkerClick(marker) {}, onMarkerReached(marker, index) {}, markers: [] }; // create a non-colliding random number function generateUUID(): string { let d = new Date().getTime(); const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { // tslint:disable-next-line:no-bitwise const r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); // tslint:disable-next-line:no-bitwise return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); }); return uuid; } function getElementBounding( element: HTMLElement ): { top: number; bottom: number; left: number; right: number; width: number; height: number; } { let elementBounding; const defaultBoundingRect = { top: 0, bottom: 0, left: 0, width: 0, height: 0, right: 0 }; try { elementBounding = element.getBoundingClientRect(); } catch (e) { elementBounding = defaultBoundingRect; } return elementBounding; } const millToTimeCode = (seconds:any, TimeFormat:TimeFormatTypes)=>{ //alert(milliseconds); var h:any = Math.floor(seconds / 3600); seconds = seconds - h * 3600; var m:any = Math.floor(seconds / 60); seconds = seconds - m * 60; var s:any = Math.floor(seconds); seconds = seconds - s; let f:any = Math.floor((seconds * 1000) / 40); if (TimeFormat === 'PAL') { f = Math.floor((seconds * 1000) / 40); } else if (TimeFormat === 'NTSC') { f = Math.floor((seconds * 30000) / 1001); } else if (TimeFormat === 'PALp') { f = Math.floor((seconds * 1000) / 20); } else if (TimeFormat === 'NTSCp') { f = Math.floor((seconds * 60000) / 1001); } else if (TimeFormat === 'STANDARD') { f = Math.floor(seconds * 1000); } else { // assume frame rate is given in numeric form f = Math.floor(seconds * TimeFormat); } // Check if we need to show hours h = (h < 10) ? ("0" + h) + ":" : h + ":"; // If hours are showing, we may need to add a leading zero. // Always show at least one digit of minutes. m = (((h) && m < 10) ? "0" + m : m) + ":"; // Check if leading zero is need for seconds s = ((s < 10) ? "0" + s : s) + ":"; f = (f < 10) ? "0" + f : f; if (TimeFormat === 'STANDARD') f = (f < 100) ? "0" + f : f; return h + m + s + f; } const NULL_INDEX = -1; export class VideoJsMarkerPlugin extends Plugin { private setting: any; private markersMap: { [key: string]: VideoJsMarker } = {}; private markersList: Array = []; private breakOverlay: any = null; private markerTip: any = null; private currentMarkerIndex = NULL_INDEX; private overlayIndex = NULL_INDEX; constructor(player: VideoJsPlayer, options?: VideoJsMarkerPluginSettings) { super(player); if (options) { this.setting = videojs.mergeOptions(defaultSetting, options); } this.player.on('loadedmetadata', () => { this.initialize(); }); } initialize(): void { if (this.setting.markerTip.display) { this.initializeMarkerTip(); } // remove existing markers if already initialized this.removeAll(); this.addMarkers(this.setting.markers); if (this.setting.breakOverlay.display) { this.initializeOverlay(); } const startOfGameMarkers: VideoJsMarker[] = this.setting.markers.filter((marker:any) => marker.text === 'start' && !marker.disabled); if (startOfGameMarkers.length) { this.player.currentTime(startOfGameMarkers[0].time); } this.onTimeUpdate(); this.player.on('timeupdate', () => this.onTimeUpdate()); this.player.off('loadedmetadata'); } getMarkers(): Array { return this.markersList; } setTimeCode():void{ const el:any = this.player.el() const timeEl:any = el.querySelector('.vjs-current-time-display') const durationEl:any = el.querySelector('.vjs-duration-display'); timeEl.text = millToTimeCode(this.player.currentTime(), this.player.options_.timeFormat); durationEl.text= millToTimeCode(this.player.duration(), this.player.options_.timeFormat); } getTimeCode():TimeCodeType{ return { playerTime:this.player.currentTime(), currentTime:millToTimeCode(this.player.currentTime(), this.player.options_.timeFormat), duration: millToTimeCode(this.player.duration(), this.player.options_.timeFormat) } } onTimeUpdate(): void { this.onUpdateMarker(); this.updateBreakOverlay(); // this.setTimeCode(); if (this.setting.onTimeUpdateAfterMarkerUpdate) { this.setting.onTimeUpdateAfterMarkerUpdate(); } } onUpdateMarker() { /* check marker reached in between markers the logic here is that it triggers a new marker reached event only if the player enters a new marker range (e.g. from marker 1 to marker 2). Thus, if player is on marker 1 and user clicked on marker 1 again, no new reached event is triggered) */ if (!this.markersList.length) { return; } this.updateMarkers(true); const getNextMarkerTime: (index: number) => number = (index: number) => { if (index < this.markersList.length - 1) { return this.setting.markerTip.time(this.markersList[index + 1]); } // next marker time of last marker would be end of video time return this.player.duration(); }; const currentTime = this.player.currentTime(); let newMarkerIndex = NULL_INDEX; if (this.currentMarkerIndex !== NULL_INDEX) { // check if staying at same marker const nextMarkerTime = getNextMarkerTime(this.currentMarkerIndex); if ( currentTime >= this.setting.markerTip.time( this.markersList[this.currentMarkerIndex] ) && currentTime < nextMarkerTime ) { return; } // check for ending (at the end current time equals player duration) if ( this.currentMarkerIndex === this.markersList.length - 1 && currentTime === this.player.duration() ) { return; } } // check first marker, no marker is selected if (currentTime < this.setting.markerTip.time(this.markersList[0])) { newMarkerIndex = NULL_INDEX; } else { // look for new index let nextMarkerTime; for (let i = 0; i < this.markersList.length; i++) { nextMarkerTime = getNextMarkerTime(i); if ( currentTime >= this.setting.markerTip.time(this.markersList[i]) && currentTime < nextMarkerTime ) { newMarkerIndex = i; break; } } } // set new marker index if (newMarkerIndex !== this.currentMarkerIndex) { // trigger event if index is not null if (newMarkerIndex !== NULL_INDEX && this.setting.onMarkerReached) { this.setting.onMarkerReached( this.markersList[newMarkerIndex], newMarkerIndex ); } this.currentMarkerIndex = newMarkerIndex; } } initializeOverlay(): void { this.breakOverlay = videojs.dom.createEl('div', { className: 'vjs-break-overlay', innerHTML: `
` }) as HTMLElement; Object.keys(this.setting.breakOverlay.style).forEach(key => { if (this.breakOverlay) { (this.breakOverlay.style as any)[key] = (this.setting.breakOverlay .style as any)[key]; } }); this.player.el().appendChild(this.breakOverlay); this.overlayIndex = NULL_INDEX; } updateBreakOverlay(): void { if (!this.setting.breakOverlay.display || this.currentMarkerIndex < 0) { return; } const currentTime = this.player.currentTime(); const marker = this.markersList[this.currentMarkerIndex]; const markerTime = this.setting.markerTip.time(marker); if ( currentTime >= markerTime && currentTime <= markerTime + this.setting.breakOverlay.displayTime ) { if (this.overlayIndex !== this.currentMarkerIndex) { this.overlayIndex = this.currentMarkerIndex; if (this.breakOverlay) { this.breakOverlay.querySelector( '.vjs-break-overlay-text' ).innerHTML = this.setting.breakOverlay.text(marker); } } if (this.breakOverlay) { this.breakOverlay.style.visibility = 'visible'; } } else { this.overlayIndex = NULL_INDEX; if (this.breakOverlay) { this.breakOverlay.style.visibility = 'hidden'; } } } setMarkderDivStyle(marker: VideoJsMarker, markerDiv: HTMLElement): void { markerDiv.className = `vjs-marker ${marker.class || ''}`; Object.keys(this.setting.markerStyle).forEach(key => { (markerDiv.style as any)[key] = (this.setting.markerStyle as any)[key]; }); // hide out-of-bound markers const ratio = marker.time / this.player.duration(); if (ratio < 0 || ratio > 1) { markerDiv.style.display = 'none'; } // set position markerDiv.style.left = this.getPosition(marker) + '%'; if (marker.duration) { markerDiv.style.width = (marker.duration / this.player.duration()) * 100 + '%'; markerDiv.style.marginLeft = '0px'; } else { const markerDivBounding = getElementBounding(markerDiv); markerDiv.style.marginLeft = -markerDivBounding.width / 2 + 'px'; } } updateMarkers(force: boolean): void { // update UI for markers whose time changed this.markersList.forEach((marker: VideoJsMarker) => { const markerDiv:any = this.player .el() .querySelector( `.vjs-marker[data-marker-key='${marker.key}']` ) as HTMLElement; const markerTime = this.setting.markerTip.time(marker); if ( force || parseFloat(markerDiv.getAttribute('data-marker-time')) !== markerTime ) { this.setMarkderDivStyle(marker, markerDiv); markerDiv.setAttribute('data-marker-time', String(markerTime)); } }); this.sortMarkersList(); } registerMarkerTipHandler(markerDiv: any): void { markerDiv.addEventListener('mouseover', () => { const marker = this.markersMap[markerDiv.getAttribute('data-marker-key')]; if (!!this.markerTip) { if (this.setting.markerTip.html) { this.markerTip.querySelector( '.vjs-tip-inner' ).innerHTML = this.setting.markerTip.html(marker); } else { (this.markerTip.querySelector( '.vjs-tip-inner' ) as HTMLElement).innerHTML = this.setting.markerTip.text(marker); } // margin-left needs to minus the padding length to align correctly with the marker this.markerTip.style.left = this.getPosition(marker) + '%'; const markerTipBounding = getElementBounding(this.markerTip); const markerDivBounding = getElementBounding(markerDiv); this.markerTip.style.marginLeft = -(markerTipBounding.width / 2) + markerDivBounding.width / 4 + 'px'; this.markerTip.style.visibility = 'visible'; } }); markerDiv.addEventListener('mouseout', () => { if (!!this.markerTip) { this.markerTip.style.visibility = 'hidden'; } }); } removeMarkers(indexArray: Array): void { // reset overlay if (!!this.breakOverlay) { this.overlayIndex = NULL_INDEX; this.breakOverlay.style.visibility = 'hidden'; } this.currentMarkerIndex = NULL_INDEX; const deleteIndexList: Array = []; indexArray.forEach((index: number) => { const marker:any = this.markersList[index]; if (marker) { // delete from memory delete this.markersMap[marker.key]; deleteIndexList.push(index); // delete from dom const el:any = this.player .el() .querySelector(`.vjs-marker[data-marker-key='${marker.key}']`); if (el) { el.parentNode.removeChild(el); } } }); // clean up markers array deleteIndexList.reverse(); deleteIndexList.forEach((deleteIndex: number) => { this.markersList.splice(deleteIndex, 1); }); // sort again this.sortMarkersList(); } next(): void { // go to the next marker from current timestamp const currentTime = this.player.currentTime(); for (const marker of this.markersList) { const markerTime = this.setting.markerTip.time(marker); if (markerTime > currentTime) { this.player.currentTime(markerTime); break; } } } prev(): void { // go to previous marker const currentTime = this.player.currentTime(); for (let i = this.markersList.length - 1; i >= 0; i--) { const markerTime = this.setting.markerTip.time(this.markersList[i]); // add a threshold if (markerTime + 0.5 < currentTime) { this.player.currentTime(markerTime); return; } } } add(newMarkers: Array): void { // add new markers given an array of index this.addMarkers(newMarkers); } addMarkers(newMarkers: Array): void { newMarkers.forEach((marker: VideoJsMarker) => { try { marker.key = generateUUID(); if(this.player!== null){ const el:any = this.player.el() el.querySelector('.vjs-progress-holder').appendChild(this.createMarkerDiv(marker)); // store marker in an internal hash map this.markersMap[marker.key] = marker; this.markersList.push(marker); } } catch (e:any) { console.error("marker not working:"+e.message); } }); this.sortMarkersList(); } sortMarkersList(): void { // sort the list by time in asc order this.markersList.sort((a, b) => { return this.setting.markerTip.time(a) - this.setting.markerTip.time(b); }); } createMarkerDiv(marker: VideoJsMarker): HTMLElement { const markerDiv = videojs.dom.createEl( 'div', {}, { 'data-marker-key': marker.key, 'data-marker-time': this.setting.markerTip.time(marker) } ) as HTMLElement; this.setMarkderDivStyle(marker, markerDiv); // bind click event to seek to marker time markerDiv.addEventListener('click', (e: Event) => { let preventDefault = false; if (typeof this.setting.onMarkerClick === 'function') { // if return false, prevent default behavior preventDefault = this.setting.onMarkerClick(marker) === false; } if (!preventDefault) { const key:any = (e.target as HTMLElement).getAttribute('data-marker-key'); this.player.currentTime( this.setting.markerTip.time(this.markersMap[key]) ); } }); if (this.setting.markerTip.display) { this.registerMarkerTipHandler(markerDiv); } return markerDiv; } getPosition(marker: VideoJsMarker): number { const liveTracker = this.player.liveTracker; const windowOrDuration = liveTracker.isLive() ? liveTracker.liveWindow() : this.player.duration(); return (this.setting.markerTip.time(marker) / windowOrDuration) * 100; } remove(indexArray: Array): void { // remove markers given an array of index this.removeMarkers(indexArray); } removeAll(): void { const indexArray = []; for (let i = 0; i < this.markersList.length; i++) { indexArray.push(i); } if(indexArray.length && this.player !== null) this.removeMarkers(indexArray); } // force - force all markers to be updated, regardless of if they have changed or not. updateTime(force: boolean): void { // notify the plugin to update the UI for changes in marker times this.updateMarkers(force); } reset(newMarkers: Array): void { // remove all the existing markers and add new ones this.removeAll(); this.addMarkers(newMarkers); } destroy(): void { // unregister the plugins and clean up even handlers this.removeAll(); if (this.breakOverlay) { this.breakOverlay.remove(); } if (this.markerTip) { this.markerTip.remove(); } this.player.off('timeupdate', this.updateBreakOverlay); // const {markers,...rest} = this.player; // delete this.player.markers; } initializeMarkerTip(): void { this.markerTip = videojs.dom.createEl('div', { className: 'vjs-tip', innerHTML: `
` }) as HTMLElement; const el:any = this.player.el(); el.querySelector('.vjs-progress-holder') .appendChild(this.markerTip); } } videojs.registerPlugin('markers', VideoJsMarkerPlugin); type TimeFormatTypes = 'PAL'| 'PALp' | 'NTSC' | 'NTSCp' | 'STANDARD'; declare module 'video.js' { export interface VideoJsPlayer { markers: (options?: VideoJsMarkerPluginSettings) => VideoJsMarkerPlugin; } export interface VideoJsPlayerOptions { timeFormat:TimeFormatTypes, markers?: boolean; } } export interface VideoJsMarker { time: number; duration?: number; text?: string; class?: string; overlayText?: string; key?: string; id?: string; disabled?: boolean; } export interface VideoJsMarkerPluginSettings { markerStyle?: object; markerTip?: { display?: boolean; html?(marker: VideoJsMarker): string; text?(marker: VideoJsMarker): string; time?(marker: VideoJsMarker): number; }; breakOverlay?: { display: boolean; displayTime: number; style: object; text(marker: VideoJsMarker): string; }; markers?: VideoJsMarker[]; onMarkerClick?(marker: VideoJsMarker): boolean | void; onMarkerReached?(marker: VideoJsMarker, index: number): void; onTimeUpdateAfterMarkerUpdate?(): void; }

0 comments:

Sample for react cookie



Set Cookie details using react

export const setUserDetails = (userDetails) => {
const { token } = userDetails;
Cookies.set('session-token', token, {
expires: 1 / 3.7, // expire in 1 hour
// secure: true,
domain: process.env.REACT_APP_HOST_NAME,
path: '/',
sameSite: 'lax',
});
};

Get Cookie details using react

export const getCurRefreshToken = () => {
return Cookies.get('refreshToken', {
domain: process.env.REACT_APP_HOST_NAME,
});
};

 Remove cookie data using react

export const removeUserDetails = () => {
const options = {
path: '/',
domain: process.env.REACT_APP_HOST_NAME,
};
Cookies.remove('session-token', options);
};

GET USER WISE DETAILS

export const getUserDetails = () => {
try {
const token = Cookies.get('session-token', {
domain: process.env.REACT_APP_HOST_NAME,
});
const { Role, ...rest } = JwtDecode(token);
rest.roles =
Role[0] === 'ADMIN'
? 'Admin'
: Role[0] === 'CONTENT'
? 'OTHER'
: false;
return token
? {
...rest,
Role,
token: token,
}
: false;
} catch (e) {
return false;
}
};


Dependancy

import Cookies from 'js-cookie';
import JwtDecode from 'jwt-decode';



0 comments:

HOW TO SETTER GETTER IN JAVA SCRIPT


HOW TO SET SETTER GETTER IN JAVA SCRIPT

function SonyDaman() {
  var myVal = null;
  var myData = [];
Object.defineProperty(this, 'myVal', {
    get: function() {
      return myData ;
    },
    set: function(value) {
      myVal = value;
      myData .push({ val: myVal });
    }
  });
}

var sd= new SonyDaman();
sd.myVal = 11;  // setter
sd.myVal = 13; // setter
sd.myVal; // 'getter!'

0 comments:

Secure RESTful Node.js app

Setup the REST Server

Create a new folder named myRESTApp. Inside that folder, create a folder named server. We will first create a new node project. Open a new terminal/prompt from inside the server folder and run
npm init
Fill it up as applicable. Now, we will add a few dependencies. Run
npm install --save express body-parser morgan jwt-simple
We are going to use Express as our server side framework, jwt-simple module to generate JSON Web Tokens. These tokens will be used as access tokens between the server and client.


Update server.js as below
var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');
var app = express();
app.use(logger('dev'));
app.use(bodyParser.json());
app.all('/*', function(req, res, next) {
  // CORS headers
  res.header("Access-Control-Allow-Origin", "*"); // restrict it to the required domain
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
  // Set custom headers for CORS
  res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key');
  if (req.method == 'OPTIONS') {
    res.status(200).end();
  } else {
    next();
  }
});
// Auth Middleware - This will check if the token is valid
// Only the requests that start with /api/v1/* will be checked for the token.
// Any URL's that do not follow the below pattern should be avoided unless you
// are sure that authentication is not needed
app.all('/api/v1/*', [require('./middlewares/validateRequest')]);
app.use('/', require('./routes'));
// If no route is matched by now, it must be a 404
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});
// Start the server
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + server.address().port);
});
 https://www.blogger.com/blogger.g?blogID=3698077727790650810#editor/target=post;postID=6251057592472405429
Create a new folder named routes inside the server folder. Inside the routes folder create a new file named index.js. This file will hold all the routes needed for our app.
Updated index.js  as below

var express = require('express');
var router = express.Router();
var auth = require('./auth.js');
var products = require('./products.js');
var user = require('./users.js');
/*
* Routes that can be accessed by any one
*/
router.post('/login', auth.login);
/*
* Routes that can be accessed only by autheticated users
*/
router.get('/api/v1/products', products.getAll);
router.get('/api/v1/product/:id', products.getOne);
router.post('/api/v1/product/', products.create);
router.put('/api/v1/product/:id', products.update);
router.delete('/api/v1/product/:id', products.delete);
/*
* Routes that can be accessed only by authenticated & authorized users
*/
router.get('/api/v1/admin/users', user.getAll);
router.get('/api/v1/admin/user/:id', user.getOne);
router.post('/api/v1/admin/user/', user.create);
router.put('/api/v1/admin/user/:id', user.update);
router.delete('/api/v1/admin/user/:id', user.delete);
module.exports = router;
Update auth.js as below
server/routes/auth.js
var jwt = require('jwt-simple');
var auth = {
  login: function(req, res) {
    var username = req.body.username || '';
    var password = req.body.password || '';
    if (username == '' || password == '') {
      res.status(401);
      res.json({
        "status": 401,
        "message": "Invalid credentials"
      });
      return;
    }
    // Fire a query to your DB and check if the credentials are valid
    var dbUserObj = auth.validate(username, password);
  
    if (!dbUserObj) { // If authentication fails, we send a 401 back
      res.status(401);
      res.json({
        "status": 401,
        "message": "Invalid credentials"
      });
      return;
    }
    if (dbUserObj) {
      // If authentication is success, we will generate a token
      // and dispatch it to the client
      res.json(genToken(dbUserObj));
    }
  },
  validate: function(username, password) {
    // spoofing the DB response for simplicity
    var dbUserObj = { // spoofing a userobject from the DB.
      name: 'arvind',
      role: 'admin',
      username: 'arvind@myapp.com'
    };
    return dbUserObj;
  },
  validateUser: function(username) {
    // spoofing the DB response for simplicity
    var dbUserObj = { // spoofing a userobject from the DB.
      name: 'arvind',
      role: 'admin',
      username: 'arvind@myapp.com'
    };
    return dbUserObj;
  },
}
// private method
function genToken(user) {
  var expires = expiresIn(7); // 7 days
  var token = jwt.encode({
    exp: expires
  }, require('../config/secret')());
  return {
    token: token,
    expires: expires,
    user: user
  };
}
function expiresIn(numDays) {
  var dateObj = new Date();
  return dateObj.setDate(dateObj.getDate() + numDays);
}
module.exports = auth;
 Now, we will create the secret. Create a new folder named config inside the server folder. Inside the config folder create a new file named secret.js and update it as
server/config/secret.js
module.exports = function() {
  return 'super.super.secret.shhh';
}
Now, we will create the dummy API for products and users. Create a file named products.js inside the routes folder and update it as below
routes/products.js
var products = {
  getAll: function(req, res) {
    var allProducts = data; // Spoof a DB call
    res.json(allProducts);
  },
  getOne: function(req, res) {
    var id = req.params.id;
    var product = data[0]; // Spoof a DB call
    res.json(product);
  },
  create: function(req, res) {
    var newProduct = req.body;
    data.push(newProduct); // Spoof a DB call
    res.json(newProduct);
  },
  update: function(req, res) {
    var updateProduct = req.body;
    var id = req.params.id;
    data[id] = updateProduct // Spoof a DB call
    res.json(updateProduct);
  },
  delete: function(req, res) {
    var id = req.params.id;
    data.splice(id, 1) // Spoof a DB call
    res.json(true);
  }
};
var data = [{
  name: 'product 1',
  id: '1'
}, {
  name: 'product 2',
  id: '2'
}, {
  name: 'product 3',
  id: '3'
}];
module.exports = products;
And create another file named users.js and update it as below
server/routes/users.js
var users = {
  getAll: function(req, res) {
    var allusers = data; // Spoof a DB call
    res.json(allusers);
  },
  getOne: function(req, res) {
    var id = req.params.id;
    var user = data[0]; // Spoof a DB call
    res.json(user);
  },
  create: function(req, res) {
    var newuser = req.body;
    data.push(newuser); // Spoof a DB call
    res.json(newuser);
  },
  update: function(req, res) {
    var updateuser = req.body;
    var id = req.params.id;
    data[id] = updateuser // Spoof a DB call
    res.json(updateuser);
  },
  delete: function(req, res) {
    var id = req.params.id;
    data.splice(id, 1) // Spoof a DB call
    res.json(true);
  }
};
var data = [{
  name: 'user 1',
  id: '1'
}, {
  name: 'user 2',
  id: '2'
}, {
  name: 'user 3',
  id: '3'
}];
module.exports = users;
server/middlewares/validateRequest.js   


var jwt = require('jwt-simple');
var validateUser = require('../routes/auth').validateUser;
module.exports = function(req, res, next) {
  // When performing a cross domain request, you will recieve
  // a preflighted request first. This is to check if our the app
  // is safe.
  // We skip the token outh for [OPTIONS] requests.
  //if(req.method == 'OPTIONS') next();
  var token = (req.body && req.body.access_token) || (req.query && req.query.access_token) || req.headers['x-access-token'];
  var key = (req.body && req.body.x_key) || (req.query && req.query.x_key) || req.headers['x-key'];
  if (token || key) {
    try {
      var decoded = jwt.decode(token, require('../config/secret.js')());
      if (decoded.exp <= Date.now()) {
        res.status(400);
        res.json({
          "status": 400,
          "message": "Token Expired"
        });
        return;
      }
      // Authorize the user to see if s/he can access our resources
      var dbUser = validateUser(key); // The key would be the logged in user's username
      if (dbUser) {
        if ((req.url.indexOf('admin') >= 0 && dbUser.role == 'admin') || (req.url.indexOf('admin') < 0 && req.url.indexOf('/api/v1/') >= 0)) {
          next(); // To move to next middleware
        } else {
          res.status(403);
          res.json({
            "status": 403,
            "message": "Not Authorized"
          });
          return;
        }
      } else {
        // No user with this name exists, respond back with a 401
        res.status(401);
        res.json({
          "status": 401,
          "message": "Invalid User"
        });
        return;
      }
    } catch (err) {
      res.status(500);
      res.json({
        "status": 500,
        "message": "Oops something went wrong",
        "error": err
      });
    }
  } else {
    res.status(401);
    res.json({
      "status": 401,
      "message": "Invalid Token or Key"
    });
    return;
  }
};
 Start our server by running  node server.js  or  nodemon server.js 
curl http://localhost:3000/api/v1/products
curl –data “{\”username\” : \”arvind@myapp.com\”, \”password\” : \”pass123\”}” -H “content-type:application/json” http://localhost:3000/login
URL : curl -H “content-type:application/json” -H “x-access-token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0MTE5MjcyMDAzNjl9.cuUKFKsf2qhQJHToP-zBmObhMwi84rhnrhH03OdyzSA” -H “x-key:arvind@myapp.com” http://localhost:3000/api/v1/products
  
 
 http://thejackalofjavascript.com/architecting-a-restful-node-js-app/
https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens 
https://github.com/scotch-io/node-token-authentication 
 
 
 

0 comments: