Refactored into strapp Modules. All in progress with File System current focus
authorjordan <jordanlavatai@gmail.com>
Tue, 1 Aug 2017 21:53:18 +0000 (14:53 -0700)
committerjordan <jordanlavatai@gmail.com>
Tue, 1 Aug 2017 21:53:18 +0000 (14:53 -0700)
bootstrap.js
strappCrypto.js [new file with mode: 0644]
strappFileManager.js [new file with mode: 0644]
strappFileSystem.js [new file with mode: 0644]
strappPeerConnection.js [new file with mode: 0644]
strappProtocolManager.js [new file with mode: 0644]

index a90539e..ba48382 100644 (file)
@@ -1,68 +1,12 @@
 /**
- * @file      Shared API 
+ * @file      Bootstrapping API 
  * @author    Jordan Lavatai and Ken Grimes
  * @version   0.0.1
- * @license   APGL-3.0
+ * @license   AGPL-3.0
  * @copyright Strapp.io
  */
 
-const dlog = (msg) => console.log(msg)
-
-/***********************/
-/** Helper functions **/
-/***********************/
-
-/* SDP Interop helper functions to be used by beginRTCOffer and beginRTCAnswer */
-
-/** @func   Determines the multimedia signaling protocol for the given session description
- *  @desc   Does some basic duck typing to determine the type of Session Description 
- *  @arg    {Object} Session Description Object
- *  @return {String} Returns 'planB' if Session Description is planB, 'Unified' if 
- *                   Session Description is Unified 
- */
-function determineSessionDescription(sessionDescription) {
-}
-
-/** @func Converts a planB session description to Unified session description
- *  @arg    {Object} Session Description Object
- *  @return {Object} PlanB Session Description
- */
-function toUnified(sessionDescription) {
-}
-
-/** @func Converts a Unified session description to planB session description 
- *  @arg    {Object} Session Description Object
- *  @return {Object} PlanB Session Description
- */
-function toPlanB(sessionDescription) {
-}
-
-/* WebSocket wielder helper functions */
-
-/* Function for setting up webSocket wielders message handler */
-/* TBD */
-/* TBD */
-
-/* SDP Negotiation helper functions */
-
-/* addRemoteIceCandidate() */
-/* addIceCandidateCreationHandler(callback for sending?) */
-/* handleIceRequest() -  WebSpocketless entity specific */
-
-
-/***********************/
-/** Exposed functions **/
-/***********************/
-
-/** @func   Attempts to create a websocket 
- *  @desc   If user agent supports web sockets, attempt to create a websocket
- *          with given domain 
- *  @arg    {String} domain - ip address or domain name of other end of websocket
- *  @return {Boolean} returns true if successful, false if unsucessful
- */
-export function createWebSocket(domain) {
-  
-}
+import fs from "fileManager"
 
 /** @func Returns public key for the user
  *  @desc Attempts to find a stored key. If unsucessful, ask user for key. If user
@@ -71,37 +15,36 @@ export function createWebSocket(domain) {
  *  @options specif
  *  @return {Object} cryptoKey object
  */
-export function resolveKey() {
-
+function resolveKey() {
+  return new Promise( (resolve, reject) => {
+    /* See if publicKey has been generated before */
+    const publicKey = fs.strappID
+    if (publicKey === '') {
+      resolve(generateKey())
+    }    
+    else {
+      resolve(publicKey)
+    }
+  })
 }
 
-/** @func Begins the SDP handshake process as the offerer
- *  @desc
- *
- *
- */
-export function beginRTCOffer() {
-}
+/* Init FileSystem */
+fs.initFileSystem()
 
-/** @func Begins the SDP handshake process as the answerer
- *  @desc
- *
- *
- */
-export function beginRTCAnswer() {
-}
+/* Find or generate key */
+let key = resolveKey()
+
+/* Auth */
+/* Authorization-header: Strapp pubkey (no answer)*/
+/* Determine answer, add answer to "." */
+
+
+/* Setup hardcoded files e.g. "..", ".", "accounts", "ice", "sdp", "log", "run" */
+/* Add the files to the filesystem only if they dont already exist /*
+
+/* Connect to host */
+
+  
 
 
-/** @func Generic way to message host from client 
- *  @desc tbd
- *  @arg  {Object} data object to be sent
- */
-export function sendHostData(data) {
-}
 
-/** @func Generic way to message client from host
- *  @desc tbd
- *  @arg  {Object} data object to be sent
- */
-export function sendClientData(data){
-}
diff --git a/strappCrypto.js b/strappCrypto.js
new file mode 100644 (file)
index 0000000..cc6fd75
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * @file      Management for bootstrapp cryptography 
+ * @desc      Makes keys, encrypts and decrypts messages
+ *            
+ * @author    Jordan Lavatai and Ken Grimes
+ * @version   0.0.1
+ * @license   AGPL-3.0
+ * @copyright Strapp.io
+ */
+
+import {setItem, getItem} from "localForage"
+
+/** @func Generates a CryptoKey and returns a SHA-256 client key
+ *  @desc Utilizes Web Crypto to create a CryptoKey using RSA specification. 
+ *        Stores both public and private representation of the key and returns 
+ *        the public key 
+ *  @return {String} clientKey
+ */
+function generateKey() { 
+  crypto.subtle.generateKey(
+    { name:'RSA-OAEP',
+      modulusLength: 2048,
+      publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
+      hash: {name: "SHA-256"}
+    },
+    true,
+    ['encrypt', 'decrypt']
+  ).then((cryptoKey) => {
+    /* TODO: Do we need to store the private key as well? */
+    crypto.subtle.exportKey('jwk', cryptoKey)
+      .then((exportedKey) => {
+        setItem('publicKey', exportedKey.publicKey)
+       setItem('privateKey', exportedKey.privateKey)
+        console.log('public key is' + getItem('publicKey'))
+        console.log('private key is' + getItem('privateKey'))
+        return exportedKey.publicKey
+      })
+  })
+}
+
+/** @func Encrypts data with a public key
+ *  @desc 
+ *  @arg {String} Public Key      
+ *  @return {Object} The encrypted data
+ */
+function encryptData(publicKey, data) {
+
+}
+/** @func Decrypts data with a private key
+ *  @desc 
+ *  @arg {String} Private key to decrypt data      
+ *  @return {Object} The decrypted data
+ */
+function decryptData(privateKey, data) {
+}
+function 
diff --git a/strappFileManager.js b/strappFileManager.js
new file mode 100644 (file)
index 0000000..6f0b9d4
--- /dev/null
@@ -0,0 +1,224 @@
+/**
+ * @file      File System Interface
+ * @desc      Provides basic file commands for interacting with Strapp
+ *            file system as well as storage (and backups) of file system
+ * @author    Jordan Lavatai and Ken Grimes
+ * @version   0.0.1
+ * @license   AGPL-3.0
+ * @copyright Strapp.io
+ */
+
+import localforage from "localforage"
+import StrappPeerConnection from "strappPeerConnection"
+
+/* File constructor */
+class File extends Object {
+  constructor(...props) {
+    super()
+    return Object.assign(this, new.target.defaults, ...props)
+  }
+  get() {
+    return this.data
+  }
+  post(postedData) {
+    this.data += postedData
+    this.lastModified = new Date()    
+  }
+  put(putData) {
+    this.data = putData
+    this.lastModified = new Date()
+  }
+  delete() {
+    this.data = ''
+    this.lastModified = new Date()
+  }
+  connect() {
+    
+  }
+  options(publicKey) {
+    return this.availPermissions(publicKey)
+  }
+}
+/* TODO: Continue to flesh this out */
+File.defaults = {
+  name: '',
+  data: '',
+  mode: {}, 
+  size: 0
+  //lastModified: new Date()?
+  //lastAccessed: new Date()?
+
+}
+
+
+/* Filesystem maintains the current session memory for the strapp instance. Files can be
+   created and killed from the filesystem without leveraging localForage. Files that are
+   in the filesystem can be stored to localForage while files that are in localForage can be loaded
+   to the filesystem. When a Filesystem is first intialized, it attempts to get its strappID it populates itself from localForage and
+   overwrites any files in its current memory. Files that have restore() as a property (which will be some method needed to 
+   make the file functions e.g. strappPeerConnections will restore() themselves lazily, i.e. when they are needed.*/
+
+   /* TODO: Should it be possible to create/preserve/destroy a file to both localForage and fileSystem? (same time) */
+   /* TODO: Should initFileSystem not overwrite files? */ 
+
+/* These are the default files on all file systems */
+let defaultFiles = [ "..", ".", "accounts", "ice", "log", "run" ]
+
+
+/* TODO: Protect data via closures? */
+const fs = {
+    /* TODO: What if files are added to file system before init is is called? */
+  initFileSystem(){
+    this.db = localforage.createInstance({ name: "database" })
+    /* Iterate through all files on localforage, adding them to FileSystem
+       and calling their restore methods */
+    this.db.iterate( (value, key, n) => {
+      /* just btw, return !undefined to exit early */
+      this.loadFile(key, true)
+      
+    }).catch( (err) => {
+      console.log(`error: ${err} when iterating through localForage during initFileSystem`)
+    })
+    /* Add the hardcoded default files if they dont already exist */
+    /* Restore these files --> need the private/public key*/
+    initialFiles.map( (val, idx, array) => {
+      if (this.fileExists(val)) {
+       let file = this.getFile(val)
+       let restoreProp = file['restore']
+       if (restoreProp === undefined && typeof restoreFx === 'function') {
+         //restore file
+       }
+       /* Else don't do anything, file exists in FS and doesnt need to be restored */          
+      }
+      else {
+       /* TODO: Remove checking for every file --> although its only for the default files which
+                 will probably be a low number. Still, unnecessary. Could make initialFiles a 
+                 Map object with fileType in it and switch(val.fileType)  */
+       if (val === '..') {
+         let file = new StrappPeerConnection()
+         /* Connect with host */
+       }
+       else {
+         /* Each default file is going to have specific permissions,  */
+         let filedata = new File()
+         filedata.name = val
+         filedata.mode = 
+           this.createFile(val,) 
+       }
+      }
+      
+    })
+    
+  },
+
+  fileExists(filename) {
+    return this.files[filename] === undefined ? false : true
+  },
+
+  /* Create a file in the file system, if specified overwrites any file that is already there
+     else does nothing */
+  createFile(filename, filedata, overwrite = false){
+    filedata.name = filename
+    if (this.files[filename] === undefined) {
+      this.files[filename] = filedata
+    }
+    else {
+      if (overwrite) {
+        console.log(`Overwriting ${filename}`)
+       this.files[filename] = filedata
+      }
+      else {
+       console.log(`Didn't overwrite file so nothing happened`)
+      }
+    }
+  }, 
+
+  /* Get a file from browser session memory */
+  /* TODO: Option to get from localForage? */
+  getFile(filename) {
+    return this.files[filename]
+  },
+
+  /* Save a file to file system*/
+  saveFile(filename, filedata) {    
+    /* TODO: Determine if file to be saved is of saveable nature e.g. SPC's cant really be saved */
+    this.db.setItem(filename, filedata)
+  },
+  
+  /* Delete file from localForage */
+  removeFile(filename) {
+    this.db.removeItem(filename)
+  },
+
+  /* Delete a file from file system */
+  killFile(filename) {
+    delete this.files[filename]
+  
+  },
+
+  /* Store file in file system to localForage */
+  storeFile(filename) {
+    this.db.setItem(filename, this.files[filename].filedata)
+  },
+
+  /* Load file from localForage to file system */
+  loadFile(filename, overwrite = false) {
+  let filedata = this.db.getItem(filename)
+  filedata = filedata.restore === undefined ? filedata : filedata.restore()
+    this.createFile(filename, filedata, overwrite)
+  },
+  
+  saveFileSystem() {
+    /* TODO: save all files in filesystem to localforage */
+  },
+  db: {},
+  files: {}
+  
+}
+
+/* File System API */
+
+
+/* Load file system from localStorage/indexedDB if strapp.js is running on a host */
+function loadFileSystem(){
+  
+}
+
+/* Store file system before shutting down if strapp.js is running on a host- */
+function storeFileSystem(){}
+
+
+
+/* addFile - adds a created file to a file */
+//@arg fileType - what to set the type property
+//@arg fileData - what to set the data property
+//@arg filePos - where to create the file
+
+/* Determine if a publicKey has permissions to execute methods
+
+/* rm - Delete file */
+
+/* ls - display file contents */
+  //open file
+//return all of file files
+
+/* cat - display file data */
+//return file data
+
+/* open - Open file */
+  //traverse to file path
+/* perm - display file permissions (if you have permissions) */
+/* find - find a file */
+//@arg fileToFind
+/* stat - info about a file */
+//@arg path - path to the file
+/* exists - determine if a file contains a file */
+//@arg {String} searchedFile - file to be searched
+//@arg {String} fileName
+//@arg {Number} Depth to look
+//@return {Boolean} true if exists, false if doesn't
+
+
+
+
+
diff --git a/strappFileSystem.js b/strappFileSystem.js
new file mode 100644 (file)
index 0000000..6f0b9d4
--- /dev/null
@@ -0,0 +1,224 @@
+/**
+ * @file      File System Interface
+ * @desc      Provides basic file commands for interacting with Strapp
+ *            file system as well as storage (and backups) of file system
+ * @author    Jordan Lavatai and Ken Grimes
+ * @version   0.0.1
+ * @license   AGPL-3.0
+ * @copyright Strapp.io
+ */
+
+import localforage from "localforage"
+import StrappPeerConnection from "strappPeerConnection"
+
+/* File constructor */
+class File extends Object {
+  constructor(...props) {
+    super()
+    return Object.assign(this, new.target.defaults, ...props)
+  }
+  get() {
+    return this.data
+  }
+  post(postedData) {
+    this.data += postedData
+    this.lastModified = new Date()    
+  }
+  put(putData) {
+    this.data = putData
+    this.lastModified = new Date()
+  }
+  delete() {
+    this.data = ''
+    this.lastModified = new Date()
+  }
+  connect() {
+    
+  }
+  options(publicKey) {
+    return this.availPermissions(publicKey)
+  }
+}
+/* TODO: Continue to flesh this out */
+File.defaults = {
+  name: '',
+  data: '',
+  mode: {}, 
+  size: 0
+  //lastModified: new Date()?
+  //lastAccessed: new Date()?
+
+}
+
+
+/* Filesystem maintains the current session memory for the strapp instance. Files can be
+   created and killed from the filesystem without leveraging localForage. Files that are
+   in the filesystem can be stored to localForage while files that are in localForage can be loaded
+   to the filesystem. When a Filesystem is first intialized, it attempts to get its strappID it populates itself from localForage and
+   overwrites any files in its current memory. Files that have restore() as a property (which will be some method needed to 
+   make the file functions e.g. strappPeerConnections will restore() themselves lazily, i.e. when they are needed.*/
+
+   /* TODO: Should it be possible to create/preserve/destroy a file to both localForage and fileSystem? (same time) */
+   /* TODO: Should initFileSystem not overwrite files? */ 
+
+/* These are the default files on all file systems */
+let defaultFiles = [ "..", ".", "accounts", "ice", "log", "run" ]
+
+
+/* TODO: Protect data via closures? */
+const fs = {
+    /* TODO: What if files are added to file system before init is is called? */
+  initFileSystem(){
+    this.db = localforage.createInstance({ name: "database" })
+    /* Iterate through all files on localforage, adding them to FileSystem
+       and calling their restore methods */
+    this.db.iterate( (value, key, n) => {
+      /* just btw, return !undefined to exit early */
+      this.loadFile(key, true)
+      
+    }).catch( (err) => {
+      console.log(`error: ${err} when iterating through localForage during initFileSystem`)
+    })
+    /* Add the hardcoded default files if they dont already exist */
+    /* Restore these files --> need the private/public key*/
+    initialFiles.map( (val, idx, array) => {
+      if (this.fileExists(val)) {
+       let file = this.getFile(val)
+       let restoreProp = file['restore']
+       if (restoreProp === undefined && typeof restoreFx === 'function') {
+         //restore file
+       }
+       /* Else don't do anything, file exists in FS and doesnt need to be restored */          
+      }
+      else {
+       /* TODO: Remove checking for every file --> although its only for the default files which
+                 will probably be a low number. Still, unnecessary. Could make initialFiles a 
+                 Map object with fileType in it and switch(val.fileType)  */
+       if (val === '..') {
+         let file = new StrappPeerConnection()
+         /* Connect with host */
+       }
+       else {
+         /* Each default file is going to have specific permissions,  */
+         let filedata = new File()
+         filedata.name = val
+         filedata.mode = 
+           this.createFile(val,) 
+       }
+      }
+      
+    })
+    
+  },
+
+  fileExists(filename) {
+    return this.files[filename] === undefined ? false : true
+  },
+
+  /* Create a file in the file system, if specified overwrites any file that is already there
+     else does nothing */
+  createFile(filename, filedata, overwrite = false){
+    filedata.name = filename
+    if (this.files[filename] === undefined) {
+      this.files[filename] = filedata
+    }
+    else {
+      if (overwrite) {
+        console.log(`Overwriting ${filename}`)
+       this.files[filename] = filedata
+      }
+      else {
+       console.log(`Didn't overwrite file so nothing happened`)
+      }
+    }
+  }, 
+
+  /* Get a file from browser session memory */
+  /* TODO: Option to get from localForage? */
+  getFile(filename) {
+    return this.files[filename]
+  },
+
+  /* Save a file to file system*/
+  saveFile(filename, filedata) {    
+    /* TODO: Determine if file to be saved is of saveable nature e.g. SPC's cant really be saved */
+    this.db.setItem(filename, filedata)
+  },
+  
+  /* Delete file from localForage */
+  removeFile(filename) {
+    this.db.removeItem(filename)
+  },
+
+  /* Delete a file from file system */
+  killFile(filename) {
+    delete this.files[filename]
+  
+  },
+
+  /* Store file in file system to localForage */
+  storeFile(filename) {
+    this.db.setItem(filename, this.files[filename].filedata)
+  },
+
+  /* Load file from localForage to file system */
+  loadFile(filename, overwrite = false) {
+  let filedata = this.db.getItem(filename)
+  filedata = filedata.restore === undefined ? filedata : filedata.restore()
+    this.createFile(filename, filedata, overwrite)
+  },
+  
+  saveFileSystem() {
+    /* TODO: save all files in filesystem to localforage */
+  },
+  db: {},
+  files: {}
+  
+}
+
+/* File System API */
+
+
+/* Load file system from localStorage/indexedDB if strapp.js is running on a host */
+function loadFileSystem(){
+  
+}
+
+/* Store file system before shutting down if strapp.js is running on a host- */
+function storeFileSystem(){}
+
+
+
+/* addFile - adds a created file to a file */
+//@arg fileType - what to set the type property
+//@arg fileData - what to set the data property
+//@arg filePos - where to create the file
+
+/* Determine if a publicKey has permissions to execute methods
+
+/* rm - Delete file */
+
+/* ls - display file contents */
+  //open file
+//return all of file files
+
+/* cat - display file data */
+//return file data
+
+/* open - Open file */
+  //traverse to file path
+/* perm - display file permissions (if you have permissions) */
+/* find - find a file */
+//@arg fileToFind
+/* stat - info about a file */
+//@arg path - path to the file
+/* exists - determine if a file contains a file */
+//@arg {String} searchedFile - file to be searched
+//@arg {String} fileName
+//@arg {Number} Depth to look
+//@return {Boolean} true if exists, false if doesn't
+
+
+
+
+
diff --git a/strappPeerConnection.js b/strappPeerConnection.js
new file mode 100644 (file)
index 0000000..8512bc2
--- /dev/null
@@ -0,0 +1,159 @@
+/**
+ * @file      Messaging module providing capability for files to communicate with each other
+ * @author    Jordan Lavatai and Ken Grimes
+ * @version   0.0.1
+ * @license   AGPL-3.0
+ * @copyright Strapp.io
+ */
+
+/** Remote Peer States:
+      unintialized
+      
+
+/* SPC default object */
+class StrappPeerConnection extends File {
+  GET() {
+  }
+  POST() {
+  }
+  CONNECT() {
+  }
+  OPTIONS() {
+  }
+  DELETE() {
+  }
+  
+}
+
+
+strappPeerConnection.defaults = Object.assign({}, File.defaults, {
+  state: '',
+  messageCount: 0,
+  messageHandler: new Map(), /* TODO: seperate handling? */
+  remotePeer: {
+    bestConnectionType: '',
+    state: '',
+    peerID: '' /* clientID of Peer* /
+  }           
+}
+
+/* GET - gets the data (queued messages) from a spc */
+/* POST - sends a msg through a spc to the remote peer */ 
+/* CONNECT - Tries to establish a connection with an spc */
+/* local or remote peer of the spc? */
+  /* Local is part of uri, make it remote*/
+
+/* File System */
+/* Convert entire file system into json objects that can be read into memory */
+    
+
+/* Send */
+/* Receive */
+/* Reconnect WebRTC */
+/* Reconnect WS */
+/* Determine remote peers bestConnectionType */
+/* Restablish connection */
+
+
+/** @func Send a message to the remote peer
+  * @desc
+  * 
+  * @arg {Object} message - message in LMKID format, except no message ID yet
+  * @this {Object} - Refers to the SPC that is calling send
+  * @return {Object} - Promise for the response from the send message
+  */
+function send(message) {
+  /* Determine if 'this' is a SPC object */
+
+  
+  /* 'send data' means to create a strapp protocol message and send it over whichever
+     transmission channel is available */
+  switch (this.state) {
+  case 'unintialized':    
+  case 'offline':
+    if (this.establishConnection(clientKey, data)) {
+      send(clientKey, data)
+    }
+    else {
+      storeMessage(this, message)
+    }
+
+    break
+  case 'disconnected':
+    this.reestablishConnection(clientKey, data)
+    /* Store the message */
+    /* Fail if reconnection attempt fails */
+    break
+  case 'polling': {
+    /* does remote peer have the ability to upgrade? */
+    /* If so, attempt to upgrade */
+    /* If upgrade fails, retry the send method else send via polling */
+    break
+  }
+  case 'webSocket': {
+    /* does remote peer have the ability to upgrade? */
+    /* If so, attempt to upgrade */
+    /* If upgrade fails, retry the send method else send via polling */
+    break
+  }
+  case 'webRTC': {
+    /* If remote peer is connected, send data */
+    /* Else Attemp to fix connection, if connection is dead, set this.state and try this again. Will
+       Enter the 'disconnected' state */
+    break
+  }
+    
+  }
+}
+  
+
+
+/** @func Attempts to connect the local peer to the remote peer 
+  * @desc
+  *
+  * @ret {boolean} True if successful, false if not
+  */
+function establishSPC() {  
+    
+}
+
+/** @func Attempts to reconnect the local peer to the remote peer 
+  * @desc This function assumes that the remotePeer property for the SPC object has
+  *       been elevated to a status higher than uninitialized.
+  *
+  * @ret {boolean} True if successful, false if not
+  */
+function reestablishSPC() {
+  /* If successful, send all the cached messages that were saved when connection was down */
+}
+
+
+/** @func Stores the message
+  * @desc
+  *
+  */
+function storeMessage() {
+}
+  
+/** @func   Determines the multimedia signaling protocol for the given session description
+ *  @desc   Does some basic duck typing to determine the type of Session Description 
+ *  @arg    {Object} Session Description Object
+ *  @return {String} Returns 'planB' if Session Description is planB, 'Unified' if 
+ *                   Session Description is Unified 
+ */
+function determineSessionDescription(sessionDescription) {
+}
+
+/** @func Converts a planB session description to Unified session description
+ *  @arg    {Object} Session Description Object
+ *  @return {Object} PlanB Session Description
+ */
+function toUnified(sessionDescription) {
+}
+
+/** @func Converts a Unified session description to planB session description 
+ *  @arg    {Object} Session Description Object
+ *  @return {Object} PlanB Session Description
+ */
+function toPlanB(sessionDescription) {
+}
diff --git a/strappProtocolManager.js b/strappProtocolManager.js
new file mode 100644 (file)
index 0000000..8aa9bfb
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * @file      Strapp Protocol Manager
+ * @author    Jordan Lavatai and Ken Grimes
+ * @version   0.0.1
+ * @license   AGPL-3.0
+ * @copyright Strapp.io
+ */
+
+import send from 'spc'
+
+/* KLMID == Key Location Method msgID Data */
+/* Convert from KLMID to HTTP  */
+/* Convert from HTTP to KLMID */
+/* Parse KLMID -> Execute method based on location */
+/* Convert Object with KLMID keys to a string */
+
+/** @func Parse the strapp protocol string 
+  * @desc KLMID stands for Location Key Method ID Data 
+  *       [Optional] Key is the clientKey that is used to authorize the method
+  *                    If not specified, this message will not have any authorizations
+  *       [Optional] Location is the location of the target file that the method will execute upon
+  *                    If not specified, target file is the current file
+  *       [Required] Method is one of the file commands available 
+  *       [Required] ID is the message ID, used when multiple messages are being sent and received
+  *       [Optional] Data is a parameter for the method e.g. PUT will replace the target files data property
+  * 
+  *        An unincluded message part needs to be indicated by a whitespace, i.e. ' ' i.e. /u{0020}.
+  *       This function is mainly called by a SPCs receive event that processes every message that a SPC
+  *       receives
+  * @arg {String} msg - String conforming to the strapp protocol 
+  * @return {Object} - Parsed object with keys corresponding to segments of strapp Protocol 
+  */
+function parseSPM(msg) {
+  /* if no location, then call the method in LMKID on the local file, i.e. "." */
+}